diff --git a/BreakingChanges.txt b/BreakingChanges.txt index 8ba547c4db9f..d217724e0b61 100644 --- a/BreakingChanges.txt +++ b/BreakingChanges.txt @@ -1,4 +1,10 @@ -2018.08.22 Version 10.0.4-rc +2018.08.11 Version 10.1.0 +* Interfaces for helper types updated to be more consistent throughout the library. All types, with the exception of the options for pipeline factories, use a fluent pattern. +* Removed RetryReader type as it's functionality was moved to be built into the DownloadResponse. RetryReaderOptions are now named ReliableDownloadOptions. +* Restructured the access conditions to be more logically adhere to their respective functions. +* Added support for context parameter on each api to allow communication with the pipeline from the application level + +2018.08.22 Version 10.0.4-rc * Changed BlobURL.startCopy sourceAccessConditions parameter to be HTTPAccessConditions as lease is not actually supported. * UploadFromFile now takes an AsynchronousFileChannel. * UploadByteBuffersToBlockBlob, UploadByteBufferToBlockBlob, and DownloadToBuffer have been removed. diff --git a/ChangeLog.txt b/ChangeLog.txt index f6ace90db96a..44bf8191dbcb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,9 @@ +2018.09.11 Version 10.1.0 +* Interfaces for helper types updated to be more consistent throughout the library. All types, with the exception of the options for pipeline factories, use a fluent pattern. +* Removed RetryReader type as it's functionality was moved to be built into the DownloadResponse. RetryReaderOptions are now named ReliableDownloadOptions. +* Restructured the access conditions to be more logically adhere to their respective functions. +* Added support for context parameter on each api to allow communication with the pipeline from the application level + 2018.08.22 Version 10.0.4-rc * Support for the 2017-11-09 REST version. Please see our REST api documentation and blogs for information about the related added features. * Support for 2018-03-28 REST version. Please see our REST api documentation and blogs for information about the related added features. diff --git a/README.md b/README.md index 4f7919e56e19..8706bdbddfd7 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ To get the binaries of this library as distributed by Microsoft, ready for use w com.microsoft.azure azure-storage-blob - 10.0.4-rc + 10.1.0 ``` @@ -131,7 +131,7 @@ public class Sample { blobURL.download(null, null, false)) .flatMap(blobsDownloadResponse -> // Verify that the blob data round-tripped correctly. - FlowableUtil.collectBytesInBuffer(blobsDownloadResponse.body()) + FlowableUtil.collectBytesInBuffer(blobsDownloadResponse.body(null)) .doOnSuccess(byteBuffer -> { if (byteBuffer.compareTo(ByteBuffer.wrap(data.getBytes())) != 0) { throw new Exception("The downloaded data does not match the uploaded data."); diff --git a/pom.xml b/pom.xml index 054cccac5db1..da2a63e7dd1b 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.microsoft.azure azure-storage-blob - 10.0.4-rc + 10.1.0 Azure Storage Blob The Azure Storage Java Blob library. @@ -61,11 +61,24 @@ + + + ossrh + Sonatype Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + default + + true + always + + + + com.microsoft.rest.v2 client-runtime - 2.0.0-beta4 + 2.0.0 junit diff --git a/src/main/java/com/microsoft/azure/storage/GeneratedAppendBlobs.java b/src/main/java/com/microsoft/azure/storage/GeneratedAppendBlobs.java index 05b7b2a91392..d32f7750a284 100644 --- a/src/main/java/com/microsoft/azure/storage/GeneratedAppendBlobs.java +++ b/src/main/java/com/microsoft/azure/storage/GeneratedAppendBlobs.java @@ -12,7 +12,12 @@ import com.microsoft.azure.storage.blob.models.AppendBlobAppendBlockResponse; import com.microsoft.azure.storage.blob.models.AppendBlobCreateResponse; +import com.microsoft.azure.storage.blob.models.AppendPositionAccessConditions; +import com.microsoft.azure.storage.blob.models.BlobHTTPHeaders; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; import com.microsoft.azure.storage.blob.models.StorageErrorException; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.DateTimeRfc1123; import com.microsoft.rest.v2.RestProxy; import com.microsoft.rest.v2.ServiceCallback; @@ -70,88 +75,67 @@ private interface AppendBlobsService { @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single create(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-blob-type") String blobType); + Single create(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-blob-type") String blobType, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single appendBlock(@HostParam("url") String url, @BodyParam("application/xml; charset=utf-8") Flowable body, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-blob-condition-maxsize") Long maxSize, @HeaderParam("x-ms-blob-condition-appendpos") Long appendPosition, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single appendBlock(Context context, @HostParam("url") String url, @BodyParam("application/xml; charset=utf-8") Flowable body, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("Content-MD5") String transactionalContentMD5, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-blob-condition-maxsize") Long maxSize, @HeaderParam("x-ms-blob-condition-appendpos") Long appendPosition, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); } /** * The Create Append Blob operation creates a new append blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void create(@NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - createAsync(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void create(Context context, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + createAsync(context, contentLength, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Create Append Blob operation creates a new append blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture createAsync(@NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(createAsync(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture createAsync(Context context, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(createAsync(context, contentLength, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Create Append Blob operation creates a new append blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single createWithRestResponseAsync(@NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single createWithRestResponseAsync(Context context, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -159,7 +143,54 @@ public Single createWithRestResponseAsync(@NonNull lon throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(metadata); + Validator.validate(blobHTTPHeaders); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String blobType = "AppendBlob"; + String blobContentType = null; + if (blobHTTPHeaders != null) { + blobContentType = blobHTTPHeaders.blobContentType(); + } + String blobContentEncoding = null; + if (blobHTTPHeaders != null) { + blobContentEncoding = blobHTTPHeaders.blobContentEncoding(); + } + String blobContentLanguage = null; + if (blobHTTPHeaders != null) { + blobContentLanguage = blobHTTPHeaders.blobContentLanguage(); + } + byte[] blobContentMD5 = null; + if (blobHTTPHeaders != null) { + blobContentMD5 = blobHTTPHeaders.blobContentMD5(); + } + String blobCacheControl = null; + if (blobHTTPHeaders != null) { + blobCacheControl = blobHTTPHeaders.blobCacheControl(); + } + String blobContentDisposition = null; + if (blobHTTPHeaders != null) { + blobContentDisposition = blobHTTPHeaders.blobContentDisposition(); + } + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } String blobContentMD5Converted = Base64Util.encodeToString(blobContentMD5); DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { @@ -169,97 +200,84 @@ public Single createWithRestResponseAsync(@NonNull lon if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.create(this.client.url(), timeout, contentLength, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, blobType); + return service.create(context, this.client.url(), timeout, contentLength, metadata, this.client.version(), requestId, blobType, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, blobCacheControl, blobContentDisposition, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Create Append Blob operation creates a new append blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable createAsync(@NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return createWithRestResponseAsync(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable createAsync(Context context, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return createWithRestResponseAsync(context, contentLength, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Append Block operation commits a new block of data to the end of an existing append blob. The Append Block operation is permitted only if the blob was created with x-ms-blob-type set to AppendBlob. Append Block is supported only on version 2015-02-21 version or later. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param maxSize Optional conditional header. The max length in bytes permitted for the append blob. If the Append Block operation would cause the blob to exceed that limit or if the blob size is already greater than the value specified in this header, the request will fail with MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param appendPosition Optional conditional header, used only for the Append Block operation. A number indicating the byte offset to compare. Append Block will succeed only if the append position is equal to this number. If it is not, the request will fail with the AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param appendPositionAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void appendBlock(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String leaseId, Long maxSize, Long appendPosition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - appendBlockAsync(body, contentLength, timeout, leaseId, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void appendBlock(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, byte[] transactionalContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, AppendPositionAccessConditions appendPositionAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + appendBlockAsync(context, body, contentLength, timeout, transactionalContentMD5, requestId, leaseAccessConditions, appendPositionAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Append Block operation commits a new block of data to the end of an existing append blob. The Append Block operation is permitted only if the blob was created with x-ms-blob-type set to AppendBlob. Append Block is supported only on version 2015-02-21 version or later. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param maxSize Optional conditional header. The max length in bytes permitted for the append blob. If the Append Block operation would cause the blob to exceed that limit or if the blob size is already greater than the value specified in this header, the request will fail with MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param appendPosition Optional conditional header, used only for the Append Block operation. A number indicating the byte offset to compare. Append Block will succeed only if the append position is equal to this number. If it is not, the request will fail with the AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param appendPositionAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture appendBlockAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String leaseId, Long maxSize, Long appendPosition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(appendBlockAsync(body, contentLength, timeout, leaseId, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture appendBlockAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, byte[] transactionalContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, AppendPositionAccessConditions appendPositionAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(appendBlockAsync(context, body, contentLength, timeout, transactionalContentMD5, requestId, leaseAccessConditions, appendPositionAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Append Block operation commits a new block of data to the end of an existing append blob. The Append Block operation is permitted only if the blob was created with x-ms-blob-type set to AppendBlob. Append Block is supported only on version 2015-02-21 version or later. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param maxSize Optional conditional header. The max length in bytes permitted for the append blob. If the Append Block operation would cause the blob to exceed that limit or if the blob size is already greater than the value specified in this header, the request will fail with MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param appendPosition Optional conditional header, used only for the Append Block operation. A number indicating the byte offset to compare. Append Block will succeed only if the append position is equal to this number. If it is not, the request will fail with the AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param appendPositionAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single appendBlockWithRestResponseAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String leaseId, Long maxSize, Long appendPosition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single appendBlockWithRestResponseAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, byte[] transactionalContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, AppendPositionAccessConditions appendPositionAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -269,7 +287,39 @@ public Single appendBlockWithRestResponseAsync(@N if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(appendPositionAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "appendblock"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + Long maxSize = null; + if (appendPositionAccessConditions != null) { + maxSize = appendPositionAccessConditions.maxSize(); + } + Long appendPosition = null; + if (appendPositionAccessConditions != null) { + appendPosition = appendPositionAccessConditions.appendPosition(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } + String transactionalContentMD5Converted = Base64Util.encodeToString(transactionalContentMD5); DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -278,28 +328,26 @@ public Single appendBlockWithRestResponseAsync(@N if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.appendBlock(this.client.url(), body, timeout, contentLength, leaseId, maxSize, appendPosition, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp); + return service.appendBlock(context, this.client.url(), body, timeout, contentLength, transactionalContentMD5Converted, this.client.version(), requestId, comp, leaseId, maxSize, appendPosition, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Append Block operation commits a new block of data to the end of an existing append blob. The Append Block operation is permitted only if the blob was created with x-ms-blob-type set to AppendBlob. Append Block is supported only on version 2015-02-21 version or later. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param maxSize Optional conditional header. The max length in bytes permitted for the append blob. If the Append Block operation would cause the blob to exceed that limit or if the blob size is already greater than the value specified in this header, the request will fail with MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param appendPosition Optional conditional header, used only for the Append Block operation. A number indicating the byte offset to compare. Append Block will succeed only if the append position is equal to this number. If it is not, the request will fail with the AppendPositionConditionNotMet error (HTTP status code 412 - Precondition Failed). - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param appendPositionAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable appendBlockAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String leaseId, Long maxSize, Long appendPosition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return appendBlockWithRestResponseAsync(body, contentLength, timeout, leaseId, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable appendBlockAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, byte[] transactionalContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, AppendPositionAccessConditions appendPositionAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return appendBlockWithRestResponseAsync(context, body, contentLength, timeout, transactionalContentMD5, requestId, leaseAccessConditions, appendPositionAccessConditions, modifiedAccessConditions) .toCompletable(); } } diff --git a/src/main/java/com/microsoft/azure/storage/GeneratedBlobs.java b/src/main/java/com/microsoft/azure/storage/GeneratedBlobs.java index 866595062591..ce23ee9d7dfc 100644 --- a/src/main/java/com/microsoft/azure/storage/GeneratedBlobs.java +++ b/src/main/java/com/microsoft/azure/storage/GeneratedBlobs.java @@ -20,6 +20,7 @@ import com.microsoft.azure.storage.blob.models.BlobDownloadResponse; import com.microsoft.azure.storage.blob.models.BlobGetAccountInfoResponse; import com.microsoft.azure.storage.blob.models.BlobGetPropertiesResponse; +import com.microsoft.azure.storage.blob.models.BlobHTTPHeaders; import com.microsoft.azure.storage.blob.models.BlobReleaseLeaseResponse; import com.microsoft.azure.storage.blob.models.BlobRenewLeaseResponse; import com.microsoft.azure.storage.blob.models.BlobSetHTTPHeadersResponse; @@ -28,7 +29,11 @@ import com.microsoft.azure.storage.blob.models.BlobStartCopyFromURLResponse; import com.microsoft.azure.storage.blob.models.BlobUndeleteResponse; import com.microsoft.azure.storage.blob.models.DeleteSnapshotsOptionType; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; +import com.microsoft.azure.storage.blob.models.SourceModifiedAccessConditions; import com.microsoft.azure.storage.blob.models.StorageErrorException; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.DateTimeRfc1123; import com.microsoft.rest.v2.RestProxy; import com.microsoft.rest.v2.ServiceCallback; @@ -90,150 +95,166 @@ private interface BlobsService { @GET("{containerName}/{blob}") @ExpectedResponses({200, 206}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single download(@HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-range-get-content-md5") Boolean rangeGetContentMD5, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId); + Single download(Context context, @HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-range-get-content-md5") Boolean rangeGetContentMD5, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @HEAD("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getProperties(@HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId); + Single getProperties(Context context, @HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @DELETE("{containerName}/{blob}") @ExpectedResponses({202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single delete(@HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-delete-snapshots") DeleteSnapshotsOptionType deleteSnapshots, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId); + Single delete(Context context, @HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-delete-snapshots") DeleteSnapshotsOptionType deleteSnapshots, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single undelete(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single undelete(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single setHTTPHeaders(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single setHTTPHeaders(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single setMetadata(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single setMetadata(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single acquireLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-duration") Integer duration, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action); + Single acquireLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-duration") Integer duration, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single releaseLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action); + Single releaseLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single renewLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action); + Single renewLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single changeLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action); + Single changeLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single breakLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-break-period") Integer breakPeriod, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action); + Single breakLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-break-period") Integer breakPeriod, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single createSnapshot(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single createSnapshot(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-lease-id") String leaseId); @PUT("{containerName}/{blob}") @ExpectedResponses({202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single startCopyFromURL(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-source-if-modified-since") DateTimeRfc1123 sourceIfModifiedSince, @HeaderParam("x-ms-source-if-unmodified-since") DateTimeRfc1123 sourceIfUnmodifiedSince, @HeaderParam("x-ms-source-if-match") String sourceIfMatches, @HeaderParam("x-ms-source-if-none-match") String sourceIfNoneMatch, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-copy-source") URL copySource, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId); + Single startCopyFromURL(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-copy-source") URL copySource, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-source-if-modified-since") DateTimeRfc1123 sourceIfModifiedSince, @HeaderParam("x-ms-source-if-unmodified-since") DateTimeRfc1123 sourceIfUnmodifiedSince, @HeaderParam("x-ms-source-if-match") String sourceIfMatch, @HeaderParam("x-ms-source-if-none-match") String sourceIfNoneMatch, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-lease-id") String leaseId); @PUT("{containerName}/{blob}") @ExpectedResponses({204}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single abortCopyFromURL(@HostParam("url") String url, @QueryParam("copyid") String copyId, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-copy-action") String copyActionAbortConstant); + Single abortCopyFromURL(Context context, @HostParam("url") String url, @QueryParam("copyid") String copyId, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-copy-action") String copyActionAbortConstant, @HeaderParam("x-ms-lease-id") String leaseId); @PUT("{containerName}/{blob}") @ExpectedResponses({200, 202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single setTier(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-access-tier") AccessTier tier, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single setTier(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-access-tier") AccessTier tier, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId); @GET("{containerName}/{blobName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getAccountInfo(@HostParam("url") String url, @HeaderParam("x-ms-version") String version, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single getAccountInfo(Context context, @HostParam("url") String url, @HeaderParam("x-ms-version") String version, @QueryParam("restype") String restype, @QueryParam("comp") String comp); } /** * The Download operation reads or downloads a blob from the system, including its metadata and properties. You can also call Download to read a snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param rangeGetContentMD5 When set to true and specified together with the Range, the service returns the MD5 hash for the range, as long as the range is less than or equal to 4 MB in size. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the Flowable<ByteBuffer> object if successful. */ - public Flowable download(String snapshot, Integer timeout, String range, String leaseId, Boolean rangeGetContentMD5, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return downloadAsync(snapshot, timeout, range, leaseId, rangeGetContentMD5, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingGet(); + public Flowable download(Context context, String snapshot, Integer timeout, String range, Boolean rangeGetContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return downloadAsync(context, snapshot, timeout, range, rangeGetContentMD5, requestId, leaseAccessConditions, modifiedAccessConditions).blockingGet(); } /** * The Download operation reads or downloads a blob from the system, including its metadata and properties. You can also call Download to read a snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param rangeGetContentMD5 When set to true and specified together with the Range, the service returns the MD5 hash for the range, as long as the range is less than or equal to 4 MB in size. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture> downloadAsync(String snapshot, Integer timeout, String range, String leaseId, Boolean rangeGetContentMD5, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback> serviceCallback) { - return ServiceFuture.fromBody(downloadAsync(snapshot, timeout, range, leaseId, rangeGetContentMD5, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture> downloadAsync(Context context, String snapshot, Integer timeout, String range, Boolean rangeGetContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback> serviceCallback) { + return ServiceFuture.fromBody(downloadAsync(context, snapshot, timeout, range, rangeGetContentMD5, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Download operation reads or downloads a blob from the system, including its metadata and properties. You can also call Download to read a snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param rangeGetContentMD5 When set to true and specified together with the Range, the service returns the MD5 hash for the range, as long as the range is less than or equal to 4 MB in size. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single downloadWithRestResponseAsync(String snapshot, Integer timeout, String range, String leaseId, Boolean rangeGetContentMD5, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single downloadWithRestResponseAsync(Context context, String snapshot, Integer timeout, String range, Boolean rangeGetContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -242,89 +263,103 @@ public Single downloadWithRestResponseAsync(String snapsho if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.download(this.client.url(), snapshot, timeout, range, leaseId, rangeGetContentMD5, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId); + return service.download(context, this.client.url(), snapshot, timeout, range, rangeGetContentMD5, this.client.version(), requestId, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Download operation reads or downloads a blob from the system, including its metadata and properties. You can also call Download to read a snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param rangeGetContentMD5 When set to true and specified together with the Range, the service returns the MD5 hash for the range, as long as the range is less than or equal to 4 MB in size. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe> downloadAsync(String snapshot, Integer timeout, String range, String leaseId, Boolean rangeGetContentMD5, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return downloadWithRestResponseAsync(snapshot, timeout, range, leaseId, rangeGetContentMD5, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Maybe> downloadAsync(Context context, String snapshot, Integer timeout, String range, Boolean rangeGetContentMD5, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return downloadWithRestResponseAsync(context, snapshot, timeout, range, rangeGetContentMD5, requestId, leaseAccessConditions, modifiedAccessConditions) .flatMapMaybe((BlobDownloadResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * The Get Properties operation returns all user-defined metadata, standard HTTP properties, and system properties for the blob. It does not return the content of the blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void getProperties(String snapshot, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - getPropertiesAsync(snapshot, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void getProperties(Context context, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + getPropertiesAsync(context, snapshot, timeout, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Get Properties operation returns all user-defined metadata, standard HTTP properties, and system properties for the blob. It does not return the content of the blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getPropertiesAsync(String snapshot, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getPropertiesAsync(snapshot, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture getPropertiesAsync(Context context, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getPropertiesAsync(context, snapshot, timeout, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Get Properties operation returns all user-defined metadata, standard HTTP properties, and system properties for the blob. It does not return the content of the blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getPropertiesWithRestResponseAsync(String snapshot, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single getPropertiesWithRestResponseAsync(Context context, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -333,90 +368,104 @@ public Single getPropertiesWithRestResponseAsync(Stri if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.getProperties(this.client.url(), snapshot, timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId); + return service.getProperties(context, this.client.url(), snapshot, timeout, this.client.version(), requestId, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Get Properties operation returns all user-defined metadata, standard HTTP properties, and system properties for the blob. It does not return the content of the blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable getPropertiesAsync(String snapshot, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return getPropertiesWithRestResponseAsync(snapshot, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable getPropertiesAsync(Context context, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return getPropertiesWithRestResponseAsync(context, snapshot, timeout, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * If the storage account's soft delete feature is disabled then, when a blob is deleted, it is permanently removed from the storage account. If the storage account's soft delete feature is enabled, then, when a blob is deleted, it is marked for deletion and becomes inaccessible immediately. However, the blob service retains the blob or snapshot for the number of days specified by the DeleteRetentionPolicy section of [Storage service properties] (Set-Blob-Service-Properties.md). After the specified number of days has passed, the blob's data is permanently removed from the storage account. Note that you continue to be charged for the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API and specify the "include=deleted" query parameter to discover which blobs and snapshots have been soft deleted. You can then use the Undelete Blob API to restore a soft-deleted blob. All other operations on a soft-deleted blob or snapshot causes the service to return an HTTP status code of 404 (ResourceNotFound). * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param deleteSnapshots Required if the blob has associated snapshots. Specify one of the following two options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's snapshots and not the blob itself. Possible values include: 'include', 'only'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void delete(String snapshot, Integer timeout, String leaseId, DeleteSnapshotsOptionType deleteSnapshots, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - deleteAsync(snapshot, timeout, leaseId, deleteSnapshots, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void delete(Context context, String snapshot, Integer timeout, DeleteSnapshotsOptionType deleteSnapshots, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + deleteAsync(context, snapshot, timeout, deleteSnapshots, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * If the storage account's soft delete feature is disabled then, when a blob is deleted, it is permanently removed from the storage account. If the storage account's soft delete feature is enabled, then, when a blob is deleted, it is marked for deletion and becomes inaccessible immediately. However, the blob service retains the blob or snapshot for the number of days specified by the DeleteRetentionPolicy section of [Storage service properties] (Set-Blob-Service-Properties.md). After the specified number of days has passed, the blob's data is permanently removed from the storage account. Note that you continue to be charged for the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API and specify the "include=deleted" query parameter to discover which blobs and snapshots have been soft deleted. You can then use the Undelete Blob API to restore a soft-deleted blob. All other operations on a soft-deleted blob or snapshot causes the service to return an HTTP status code of 404 (ResourceNotFound). * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param deleteSnapshots Required if the blob has associated snapshots. Specify one of the following two options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's snapshots and not the blob itself. Possible values include: 'include', 'only'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture deleteAsync(String snapshot, Integer timeout, String leaseId, DeleteSnapshotsOptionType deleteSnapshots, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(deleteAsync(snapshot, timeout, leaseId, deleteSnapshots, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture deleteAsync(Context context, String snapshot, Integer timeout, DeleteSnapshotsOptionType deleteSnapshots, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(deleteAsync(context, snapshot, timeout, deleteSnapshots, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * If the storage account's soft delete feature is disabled then, when a blob is deleted, it is permanently removed from the storage account. If the storage account's soft delete feature is enabled, then, when a blob is deleted, it is marked for deletion and becomes inaccessible immediately. However, the blob service retains the blob or snapshot for the number of days specified by the DeleteRetentionPolicy section of [Storage service properties] (Set-Blob-Service-Properties.md). After the specified number of days has passed, the blob's data is permanently removed from the storage account. Note that you continue to be charged for the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API and specify the "include=deleted" query parameter to discover which blobs and snapshots have been soft deleted. You can then use the Undelete Blob API to restore a soft-deleted blob. All other operations on a soft-deleted blob or snapshot causes the service to return an HTTP status code of 404 (ResourceNotFound). * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param deleteSnapshots Required if the blob has associated snapshots. Specify one of the following two options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's snapshots and not the blob itself. Possible values include: 'include', 'only'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single deleteWithRestResponseAsync(String snapshot, Integer timeout, String leaseId, DeleteSnapshotsOptionType deleteSnapshots, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single deleteWithRestResponseAsync(Context context, String snapshot, Integer timeout, DeleteSnapshotsOptionType deleteSnapshots, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -425,64 +474,65 @@ public Single deleteWithRestResponseAsync(String snapshot, I if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.delete(this.client.url(), snapshot, timeout, leaseId, deleteSnapshots, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId); + return service.delete(context, this.client.url(), snapshot, timeout, deleteSnapshots, this.client.version(), requestId, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * If the storage account's soft delete feature is disabled then, when a blob is deleted, it is permanently removed from the storage account. If the storage account's soft delete feature is enabled, then, when a blob is deleted, it is marked for deletion and becomes inaccessible immediately. However, the blob service retains the blob or snapshot for the number of days specified by the DeleteRetentionPolicy section of [Storage service properties] (Set-Blob-Service-Properties.md). After the specified number of days has passed, the blob's data is permanently removed from the storage account. Note that you continue to be charged for the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API and specify the "include=deleted" query parameter to discover which blobs and snapshots have been soft deleted. You can then use the Undelete Blob API to restore a soft-deleted blob. All other operations on a soft-deleted blob or snapshot causes the service to return an HTTP status code of 404 (ResourceNotFound). * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param deleteSnapshots Required if the blob has associated snapshots. Specify one of the following two options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's snapshots and not the blob itself. Possible values include: 'include', 'only'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable deleteAsync(String snapshot, Integer timeout, String leaseId, DeleteSnapshotsOptionType deleteSnapshots, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return deleteWithRestResponseAsync(snapshot, timeout, leaseId, deleteSnapshots, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable deleteAsync(Context context, String snapshot, Integer timeout, DeleteSnapshotsOptionType deleteSnapshots, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return deleteWithRestResponseAsync(context, snapshot, timeout, deleteSnapshots, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * Undelete a blob that was previously soft deleted. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void undelete(Integer timeout, String requestId) { - undeleteAsync(timeout, requestId).blockingAwait(); + public void undelete(Context context, Integer timeout, String requestId) { + undeleteAsync(context, timeout, requestId).blockingAwait(); } /** * Undelete a blob that was previously soft deleted. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture undeleteAsync(Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(undeleteAsync(timeout, requestId), serviceCallback); + public ServiceFuture undeleteAsync(Context context, Integer timeout, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(undeleteAsync(context, timeout, requestId), serviceCallback); } /** * Undelete a blob that was previously soft deleted. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single undeleteWithRestResponseAsync(Integer timeout, String requestId) { + public Single undeleteWithRestResponseAsync(Context context, Integer timeout, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -490,97 +540,124 @@ public Single undeleteWithRestResponseAsync(Integer timeou throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } final String comp = "undelete"; - return service.undelete(this.client.url(), timeout, this.client.version(), requestId, comp); + return service.undelete(context, this.client.url(), timeout, this.client.version(), requestId, comp); } /** * Undelete a blob that was previously soft deleted. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable undeleteAsync(Integer timeout, String requestId) { - return undeleteWithRestResponseAsync(timeout, requestId) + public Completable undeleteAsync(Context context, Integer timeout, String requestId) { + return undeleteWithRestResponseAsync(context, timeout, requestId) .toCompletable(); } /** * The Set HTTP Headers operation sets system properties on the blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void setHTTPHeaders(Integer timeout, String blobCacheControl, String blobContentType, byte[] blobContentMD5, String blobContentEncoding, String blobContentLanguage, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String blobContentDisposition, String requestId) { - setHTTPHeadersAsync(timeout, blobCacheControl, blobContentType, blobContentMD5, blobContentEncoding, blobContentLanguage, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobContentDisposition, requestId).blockingAwait(); + public void setHTTPHeaders(Context context, Integer timeout, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + setHTTPHeadersAsync(context, timeout, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Set HTTP Headers operation sets system properties on the blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture setHTTPHeadersAsync(Integer timeout, String blobCacheControl, String blobContentType, byte[] blobContentMD5, String blobContentEncoding, String blobContentLanguage, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String blobContentDisposition, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(setHTTPHeadersAsync(timeout, blobCacheControl, blobContentType, blobContentMD5, blobContentEncoding, blobContentLanguage, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobContentDisposition, requestId), serviceCallback); + public ServiceFuture setHTTPHeadersAsync(Context context, Integer timeout, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(setHTTPHeadersAsync(context, timeout, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Set HTTP Headers operation sets system properties on the blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single setHTTPHeadersWithRestResponseAsync(Integer timeout, String blobCacheControl, String blobContentType, byte[] blobContentMD5, String blobContentEncoding, String blobContentLanguage, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String blobContentDisposition, String requestId) { + public Single setHTTPHeadersWithRestResponseAsync(Context context, Integer timeout, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(blobHTTPHeaders); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "properties"; + String blobCacheControl = null; + if (blobHTTPHeaders != null) { + blobCacheControl = blobHTTPHeaders.blobCacheControl(); + } + String blobContentType = null; + if (blobHTTPHeaders != null) { + blobContentType = blobHTTPHeaders.blobContentType(); + } + byte[] blobContentMD5 = null; + if (blobHTTPHeaders != null) { + blobContentMD5 = blobHTTPHeaders.blobContentMD5(); + } + String blobContentEncoding = null; + if (blobHTTPHeaders != null) { + blobContentEncoding = blobHTTPHeaders.blobContentEncoding(); + } + String blobContentLanguage = null; + if (blobHTTPHeaders != null) { + blobContentLanguage = blobHTTPHeaders.blobContentLanguage(); + } + String blobContentDisposition = null; + if (blobHTTPHeaders != null) { + blobContentDisposition = blobHTTPHeaders.blobContentDisposition(); + } + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } String blobContentMD5Converted = Base64Util.encodeToString(blobContentMD5); DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { @@ -590,86 +667,73 @@ public Single setHTTPHeadersWithRestResponseAsync(In if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.setHTTPHeaders(this.client.url(), timeout, blobCacheControl, blobContentType, blobContentMD5Converted, blobContentEncoding, blobContentLanguage, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, blobContentDisposition, this.client.version(), requestId, comp); + return service.setHTTPHeaders(context, this.client.url(), timeout, this.client.version(), requestId, comp, blobCacheControl, blobContentType, blobContentMD5Converted, blobContentEncoding, blobContentLanguage, blobContentDisposition, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Set HTTP Headers operation sets system properties on the blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable setHTTPHeadersAsync(Integer timeout, String blobCacheControl, String blobContentType, byte[] blobContentMD5, String blobContentEncoding, String blobContentLanguage, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String blobContentDisposition, String requestId) { - return setHTTPHeadersWithRestResponseAsync(timeout, blobCacheControl, blobContentType, blobContentMD5, blobContentEncoding, blobContentLanguage, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobContentDisposition, requestId) + public Completable setHTTPHeadersAsync(Context context, Integer timeout, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return setHTTPHeadersWithRestResponseAsync(context, timeout, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Set Blob Metadata operation sets user-defined metadata for the specified blob as one or more name-value pairs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void setMetadata(Integer timeout, Map metadata, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - setMetadataAsync(timeout, metadata, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void setMetadata(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + setMetadataAsync(context, timeout, metadata, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Set Blob Metadata operation sets user-defined metadata for the specified blob as one or more name-value pairs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture setMetadataAsync(Integer timeout, Map metadata, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(setMetadataAsync(timeout, metadata, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture setMetadataAsync(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(setMetadataAsync(context, timeout, metadata, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Set Blob Metadata operation sets user-defined metadata for the specified blob as one or more name-value pairs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single setMetadataWithRestResponseAsync(Integer timeout, Map metadata, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single setMetadataWithRestResponseAsync(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -677,7 +741,29 @@ public Single setMetadataWithRestResponseAsync(Integer throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(metadata); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "metadata"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -686,89 +772,98 @@ public Single setMetadataWithRestResponseAsync(Integer if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.setMetadata(this.client.url(), timeout, metadata, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp); + return service.setMetadata(context, this.client.url(), timeout, metadata, this.client.version(), requestId, comp, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Set Blob Metadata operation sets user-defined metadata for the specified blob as one or more name-value pairs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable setMetadataAsync(Integer timeout, Map metadata, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return setMetadataWithRestResponseAsync(timeout, metadata, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable setMetadataAsync(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return setMetadataWithRestResponseAsync(context, timeout, metadata, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void acquireLease(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - acquireLeaseAsync(timeout, duration, proposedLeaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void acquireLease(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + acquireLeaseAsync(context, timeout, duration, proposedLeaseId, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture acquireLeaseAsync(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(acquireLeaseAsync(timeout, duration, proposedLeaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture acquireLeaseAsync(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(acquireLeaseAsync(context, timeout, duration, proposedLeaseId, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single acquireLeaseWithRestResponseAsync(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single acquireLeaseWithRestResponseAsync(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String action = "acquire"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -777,78 +872,70 @@ public Single acquireLeaseWithRestResponseAsync(Intege if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.acquireLease(this.client.url(), timeout, duration, proposedLeaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp, action); + return service.acquireLease(context, this.client.url(), timeout, duration, proposedLeaseId, this.client.version(), requestId, comp, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable acquireLeaseAsync(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return acquireLeaseWithRestResponseAsync(timeout, duration, proposedLeaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable acquireLeaseAsync(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return acquireLeaseWithRestResponseAsync(context, timeout, duration, proposedLeaseId, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void releaseLease(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - releaseLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void releaseLease(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + releaseLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture releaseLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(releaseLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture releaseLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(releaseLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single releaseLeaseWithRestResponseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single releaseLeaseWithRestResponseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -858,8 +945,25 @@ public Single releaseLeaseWithRestResponseAsync(@NonNu if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String action = "release"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -868,77 +972,69 @@ public Single releaseLeaseWithRestResponseAsync(@NonNu if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.releaseLease(this.client.url(), timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp, action); + return service.releaseLease(context, this.client.url(), timeout, leaseId, this.client.version(), requestId, comp, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable releaseLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return releaseLeaseWithRestResponseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable releaseLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return releaseLeaseWithRestResponseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void renewLease(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - renewLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void renewLease(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + renewLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture renewLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(renewLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture renewLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(renewLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single renewLeaseWithRestResponseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single renewLeaseWithRestResponseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -948,8 +1044,25 @@ public Single renewLeaseWithRestResponseAsync(@NonNull S if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String action = "renew"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -958,80 +1071,72 @@ public Single renewLeaseWithRestResponseAsync(@NonNull S if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.renewLease(this.client.url(), timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp, action); + return service.renewLease(context, this.client.url(), timeout, leaseId, this.client.version(), requestId, comp, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable renewLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return renewLeaseWithRestResponseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable renewLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return renewLeaseWithRestResponseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void changeLease(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - changeLeaseAsync(leaseId, proposedLeaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void changeLease(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + changeLeaseAsync(context, leaseId, proposedLeaseId, timeout, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture changeLeaseAsync(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(changeLeaseAsync(leaseId, proposedLeaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture changeLeaseAsync(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(changeLeaseAsync(context, leaseId, proposedLeaseId, timeout, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single changeLeaseWithRestResponseAsync(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single changeLeaseWithRestResponseAsync(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1044,8 +1149,25 @@ public Single changeLeaseWithRestResponseAsync(@NonNull if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String action = "change"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -1054,86 +1176,95 @@ public Single changeLeaseWithRestResponseAsync(@NonNull if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.changeLease(this.client.url(), timeout, leaseId, proposedLeaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp, action); + return service.changeLease(context, this.client.url(), timeout, leaseId, proposedLeaseId, this.client.version(), requestId, comp, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable changeLeaseAsync(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return changeLeaseWithRestResponseAsync(leaseId, proposedLeaseId, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable changeLeaseAsync(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return changeLeaseWithRestResponseAsync(context, leaseId, proposedLeaseId, timeout, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void breakLease(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - breakLeaseAsync(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void breakLease(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + breakLeaseAsync(context, timeout, breakPeriod, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture breakLeaseAsync(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(breakLeaseAsync(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture breakLeaseAsync(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(breakLeaseAsync(context, timeout, breakPeriod, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single breakLeaseWithRestResponseAsync(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single breakLeaseWithRestResponseAsync(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String action = "break"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -1142,80 +1273,72 @@ public Single breakLeaseWithRestResponseAsync(Integer ti if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.breakLease(this.client.url(), timeout, breakPeriod, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp, action); + return service.breakLease(context, this.client.url(), timeout, breakPeriod, this.client.version(), requestId, comp, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete operations. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable breakLeaseAsync(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return breakLeaseWithRestResponseAsync(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable breakLeaseAsync(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return breakLeaseWithRestResponseAsync(context, timeout, breakPeriod, requestId, modifiedAccessConditions) .toCompletable(); } /** * The Create Snapshot operation creates a read-only snapshot of a blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void createSnapshot(Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId) { - createSnapshotAsync(timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseId, requestId).blockingAwait(); + public void createSnapshot(Context context, Integer timeout, Map metadata, String requestId, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions) { + createSnapshotAsync(context, timeout, metadata, requestId, modifiedAccessConditions, leaseAccessConditions).blockingAwait(); } /** * The Create Snapshot operation creates a read-only snapshot of a blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture createSnapshotAsync(Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(createSnapshotAsync(timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseId, requestId), serviceCallback); + public ServiceFuture createSnapshotAsync(Context context, Integer timeout, Map metadata, String requestId, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(createSnapshotAsync(context, timeout, metadata, requestId, modifiedAccessConditions, leaseAccessConditions), serviceCallback); } /** * The Create Snapshot operation creates a read-only snapshot of a blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single createSnapshotWithRestResponseAsync(Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId) { + public Single createSnapshotWithRestResponseAsync(Context context, Integer timeout, Map metadata, String requestId, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1223,7 +1346,29 @@ public Single createSnapshotWithRestResponseAsync(In throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(metadata); + Validator.validate(modifiedAccessConditions); + Validator.validate(leaseAccessConditions); final String comp = "snapshot"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -1232,96 +1377,79 @@ public Single createSnapshotWithRestResponseAsync(In if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.createSnapshot(this.client.url(), timeout, metadata, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, leaseId, this.client.version(), requestId, comp); + return service.createSnapshot(context, this.client.url(), timeout, metadata, this.client.version(), requestId, comp, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch, leaseId); } /** * The Create Snapshot operation creates a read-only snapshot of a blob. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable createSnapshotAsync(Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId) { - return createSnapshotWithRestResponseAsync(timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseId, requestId) + public Completable createSnapshotAsync(Context context, Integer timeout, Map metadata, String requestId, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions) { + return createSnapshotWithRestResponseAsync(context, timeout, metadata, requestId, modifiedAccessConditions, leaseAccessConditions) .toCompletable(); } /** * The Start Copy From URL operation copies a blob or an internet resource to a new blob. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param sourceIfModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param sourceIfUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param sourceIfMatches Specify an ETag value to operate only on blobs with a matching value. - * @param sourceIfNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param sourceModifiedAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void startCopyFromURL(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime sourceIfModifiedSince, OffsetDateTime sourceIfUnmodifiedSince, String sourceIfMatches, String sourceIfNoneMatch, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId) { - startCopyFromURLAsync(copySource, timeout, metadata, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatches, sourceIfNoneMatch, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseId, requestId).blockingAwait(); + public void startCopyFromURL(Context context, @NonNull URL copySource, Integer timeout, Map metadata, String requestId, SourceModifiedAccessConditions sourceModifiedAccessConditions, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions) { + startCopyFromURLAsync(context, copySource, timeout, metadata, requestId, sourceModifiedAccessConditions, modifiedAccessConditions, leaseAccessConditions).blockingAwait(); } /** * The Start Copy From URL operation copies a blob or an internet resource to a new blob. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param sourceIfModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param sourceIfUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param sourceIfMatches Specify an ETag value to operate only on blobs with a matching value. - * @param sourceIfNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param sourceModifiedAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture startCopyFromURLAsync(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime sourceIfModifiedSince, OffsetDateTime sourceIfUnmodifiedSince, String sourceIfMatches, String sourceIfNoneMatch, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(startCopyFromURLAsync(copySource, timeout, metadata, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatches, sourceIfNoneMatch, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseId, requestId), serviceCallback); + public ServiceFuture startCopyFromURLAsync(Context context, @NonNull URL copySource, Integer timeout, Map metadata, String requestId, SourceModifiedAccessConditions sourceModifiedAccessConditions, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(startCopyFromURLAsync(context, copySource, timeout, metadata, requestId, sourceModifiedAccessConditions, modifiedAccessConditions, leaseAccessConditions), serviceCallback); } /** * The Start Copy From URL operation copies a blob or an internet resource to a new blob. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param sourceIfModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param sourceIfUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param sourceIfMatches Specify an ETag value to operate only on blobs with a matching value. - * @param sourceIfNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param sourceModifiedAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single startCopyFromURLWithRestResponseAsync(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime sourceIfModifiedSince, OffsetDateTime sourceIfUnmodifiedSince, String sourceIfMatches, String sourceIfNoneMatch, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId) { + public Single startCopyFromURLWithRestResponseAsync(Context context, @NonNull URL copySource, Integer timeout, Map metadata, String requestId, SourceModifiedAccessConditions sourceModifiedAccessConditions, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1333,6 +1461,45 @@ public Single startCopyFromURLWithRestResponseAsyn } Validator.validate(metadata); Validator.validate(copySource); + Validator.validate(sourceModifiedAccessConditions); + Validator.validate(modifiedAccessConditions); + Validator.validate(leaseAccessConditions); + OffsetDateTime sourceIfModifiedSince = null; + if (sourceModifiedAccessConditions != null) { + sourceIfModifiedSince = sourceModifiedAccessConditions.sourceIfModifiedSince(); + } + OffsetDateTime sourceIfUnmodifiedSince = null; + if (sourceModifiedAccessConditions != null) { + sourceIfUnmodifiedSince = sourceModifiedAccessConditions.sourceIfUnmodifiedSince(); + } + String sourceIfMatch = null; + if (sourceModifiedAccessConditions != null) { + sourceIfMatch = sourceModifiedAccessConditions.sourceIfMatch(); + } + String sourceIfNoneMatch = null; + if (sourceModifiedAccessConditions != null) { + sourceIfNoneMatch = sourceModifiedAccessConditions.sourceIfNoneMatch(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } DateTimeRfc1123 sourceIfModifiedSinceConverted = null; if (sourceIfModifiedSince != null) { sourceIfModifiedSinceConverted = new DateTimeRfc1123(sourceIfModifiedSince); @@ -1349,74 +1516,72 @@ public Single startCopyFromURLWithRestResponseAsyn if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.startCopyFromURL(this.client.url(), timeout, metadata, sourceIfModifiedSinceConverted, sourceIfUnmodifiedSinceConverted, sourceIfMatches, sourceIfNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, copySource, leaseId, this.client.version(), requestId); + return service.startCopyFromURL(context, this.client.url(), timeout, metadata, copySource, this.client.version(), requestId, sourceIfModifiedSinceConverted, sourceIfUnmodifiedSinceConverted, sourceIfMatch, sourceIfNoneMatch, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch, leaseId); } /** * The Start Copy From URL operation copies a blob or an internet resource to a new blob. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param sourceIfModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param sourceIfUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param sourceIfMatches Specify an ETag value to operate only on blobs with a matching value. - * @param sourceIfNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param sourceModifiedAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable startCopyFromURLAsync(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime sourceIfModifiedSince, OffsetDateTime sourceIfUnmodifiedSince, String sourceIfMatches, String sourceIfNoneMatch, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String leaseId, String requestId) { - return startCopyFromURLWithRestResponseAsync(copySource, timeout, metadata, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatches, sourceIfNoneMatch, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseId, requestId) + public Completable startCopyFromURLAsync(Context context, @NonNull URL copySource, Integer timeout, Map metadata, String requestId, SourceModifiedAccessConditions sourceModifiedAccessConditions, ModifiedAccessConditions modifiedAccessConditions, LeaseAccessConditions leaseAccessConditions) { + return startCopyFromURLWithRestResponseAsync(context, copySource, timeout, metadata, requestId, sourceModifiedAccessConditions, modifiedAccessConditions, leaseAccessConditions) .toCompletable(); } /** * The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a destination blob with zero length and full metadata. * + * @param context The context to associate with this operation. * @param copyId The copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void abortCopyFromURL(@NonNull String copyId, Integer timeout, String leaseId, String requestId) { - abortCopyFromURLAsync(copyId, timeout, leaseId, requestId).blockingAwait(); + public void abortCopyFromURL(Context context, @NonNull String copyId, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + abortCopyFromURLAsync(context, copyId, timeout, requestId, leaseAccessConditions).blockingAwait(); } /** * The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a destination blob with zero length and full metadata. * + * @param context The context to associate with this operation. * @param copyId The copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture abortCopyFromURLAsync(@NonNull String copyId, Integer timeout, String leaseId, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(abortCopyFromURLAsync(copyId, timeout, leaseId, requestId), serviceCallback); + public ServiceFuture abortCopyFromURLAsync(Context context, @NonNull String copyId, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(abortCopyFromURLAsync(context, copyId, timeout, requestId, leaseAccessConditions), serviceCallback); } /** * The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a destination blob with zero length and full metadata. * + * @param context The context to associate with this operation. * @param copyId The copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single abortCopyFromURLWithRestResponseAsync(@NonNull String copyId, Integer timeout, String leaseId, String requestId) { + public Single abortCopyFromURLWithRestResponseAsync(Context context, @NonNull String copyId, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1426,64 +1591,76 @@ public Single abortCopyFromURLWithRestResponseAsyn if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); final String comp = "copy"; final String copyActionAbortConstant = "abort"; - return service.abortCopyFromURL(this.client.url(), copyId, timeout, leaseId, this.client.version(), requestId, comp, copyActionAbortConstant); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + return service.abortCopyFromURL(context, this.client.url(), copyId, timeout, this.client.version(), requestId, comp, copyActionAbortConstant, leaseId); } /** * The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a destination blob with zero length and full metadata. * + * @param context The context to associate with this operation. * @param copyId The copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable abortCopyFromURLAsync(@NonNull String copyId, Integer timeout, String leaseId, String requestId) { - return abortCopyFromURLWithRestResponseAsync(copyId, timeout, leaseId, requestId) + public Completable abortCopyFromURLAsync(Context context, @NonNull String copyId, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return abortCopyFromURLWithRestResponseAsync(context, copyId, timeout, requestId, leaseAccessConditions) .toCompletable(); } /** * The Set Tier operation sets the tier on a blob. The operation is allowed on a page blob in a premium storage account and on a block blob in a blob storage account (locally redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not update the blob's ETag. * + * @param context The context to associate with this operation. * @param tier Indicates the tier to be set on the blob. Possible values include: 'P4', 'P6', 'P10', 'P20', 'P30', 'P40', 'P50', 'Hot', 'Cool', 'Archive'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void setTier(@NonNull AccessTier tier, Integer timeout, String requestId) { - setTierAsync(tier, timeout, requestId).blockingAwait(); + public void setTier(Context context, @NonNull AccessTier tier, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + setTierAsync(context, tier, timeout, requestId, leaseAccessConditions).blockingAwait(); } /** * The Set Tier operation sets the tier on a blob. The operation is allowed on a page blob in a premium storage account and on a block blob in a blob storage account (locally redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not update the blob's ETag. * + * @param context The context to associate with this operation. * @param tier Indicates the tier to be set on the blob. Possible values include: 'P4', 'P6', 'P10', 'P20', 'P30', 'P40', 'P50', 'Hot', 'Cool', 'Archive'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture setTierAsync(@NonNull AccessTier tier, Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(setTierAsync(tier, timeout, requestId), serviceCallback); + public ServiceFuture setTierAsync(Context context, @NonNull AccessTier tier, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(setTierAsync(context, tier, timeout, requestId, leaseAccessConditions), serviceCallback); } /** * The Set Tier operation sets the tier on a blob. The operation is allowed on a page blob in a premium storage account and on a block blob in a blob storage account (locally redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not update the blob's ETag. * + * @param context The context to associate with this operation. * @param tier Indicates the tier to be set on the blob. Possible values include: 'P4', 'P6', 'P10', 'P20', 'P30', 'P40', 'P50', 'Hot', 'Cool', 'Archive'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single setTierWithRestResponseAsync(@NonNull AccessTier tier, Integer timeout, String requestId) { + public Single setTierWithRestResponseAsync(Context context, @NonNull AccessTier tier, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1493,51 +1670,63 @@ public Single setTierWithRestResponseAsync(@NonNull AccessT if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); final String comp = "tier"; - return service.setTier(this.client.url(), timeout, tier, this.client.version(), requestId, comp); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + return service.setTier(context, this.client.url(), timeout, tier, this.client.version(), requestId, comp, leaseId); } /** * The Set Tier operation sets the tier on a blob. The operation is allowed on a page blob in a premium storage account and on a block blob in a blob storage account (locally redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not update the blob's ETag. * + * @param context The context to associate with this operation. * @param tier Indicates the tier to be set on the blob. Possible values include: 'P4', 'P6', 'P10', 'P20', 'P30', 'P40', 'P50', 'Hot', 'Cool', 'Archive'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable setTierAsync(@NonNull AccessTier tier, Integer timeout, String requestId) { - return setTierWithRestResponseAsync(tier, timeout, requestId) + public Completable setTierAsync(Context context, @NonNull AccessTier tier, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return setTierWithRestResponseAsync(context, tier, timeout, requestId, leaseAccessConditions) .toCompletable(); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void getAccountInfo() { - getAccountInfoAsync().blockingAwait(); + public void getAccountInfo(Context context) { + getAccountInfoAsync(context).blockingAwait(); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getAccountInfoAsync(ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getAccountInfoAsync(), serviceCallback); + public ServiceFuture getAccountInfoAsync(Context context, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getAccountInfoAsync(context), serviceCallback); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getAccountInfoWithRestResponseAsync() { + public Single getAccountInfoWithRestResponseAsync(Context context) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1546,16 +1735,18 @@ public Single getAccountInfoWithRestResponseAsync() } final String restype = "account"; final String comp = "properties"; - return service.getAccountInfo(this.client.url(), this.client.version(), restype, comp); + return service.getAccountInfo(context, this.client.url(), this.client.version(), restype, comp); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable getAccountInfoAsync() { - return getAccountInfoWithRestResponseAsync() + public Completable getAccountInfoAsync(Context context) { + return getAccountInfoWithRestResponseAsync(context) .toCompletable(); } } diff --git a/src/main/java/com/microsoft/azure/storage/GeneratedBlockBlobs.java b/src/main/java/com/microsoft/azure/storage/GeneratedBlockBlobs.java index 88f33e6e32cf..fb6eb986f744 100644 --- a/src/main/java/com/microsoft/azure/storage/GeneratedBlockBlobs.java +++ b/src/main/java/com/microsoft/azure/storage/GeneratedBlockBlobs.java @@ -10,6 +10,7 @@ package com.microsoft.azure.storage; +import com.microsoft.azure.storage.blob.models.BlobHTTPHeaders; import com.microsoft.azure.storage.blob.models.BlockBlobCommitBlockListResponse; import com.microsoft.azure.storage.blob.models.BlockBlobGetBlockListResponse; import com.microsoft.azure.storage.blob.models.BlockBlobStageBlockFromURLResponse; @@ -18,7 +19,10 @@ import com.microsoft.azure.storage.blob.models.BlockList; import com.microsoft.azure.storage.blob.models.BlockListType; import com.microsoft.azure.storage.blob.models.BlockLookupList; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; import com.microsoft.azure.storage.blob.models.StorageErrorException; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.DateTimeRfc1123; import com.microsoft.rest.v2.RestProxy; import com.microsoft.rest.v2.ServiceCallback; @@ -79,106 +83,85 @@ private interface BlockBlobsService { @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single upload(@HostParam("url") String url, @BodyParam("application/octet-stream") Flowable body, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-blob-type") String blobType); + Single upload(Context context, @HostParam("url") String url, @BodyParam("application/octet-stream") Flowable body, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-blob-type") String blobType, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single stageBlock(@HostParam("url") String url, @QueryParam("blockid") String blockId, @HeaderParam("Content-Length") long contentLength, @BodyParam("application/octet-stream") Flowable body, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single stageBlock(Context context, @HostParam("url") String url, @QueryParam("blockid") String blockId, @HeaderParam("Content-Length") long contentLength, @HeaderParam("Content-MD5") String transactionalContentMD5, @BodyParam("application/octet-stream") Flowable body, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single stageBlockFromURL(@HostParam("url") String url, @QueryParam("blockid") String blockId, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-copy-source") URL copySource, @HeaderParam("x-ms-source-range") String sourceRange, @HeaderParam("x-ms-source-content-md5") String sourceContentMD5, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single stageBlockFromURL(Context context, @HostParam("url") String url, @QueryParam("blockid") String blockId, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-copy-source") URL copySource, @HeaderParam("x-ms-source-range") String sourceRange, @HeaderParam("x-ms-source-content-md5") String sourceContentMD5, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single commitBlockList(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @BodyParam("application/xml; charset=utf-8") BlockLookupList blocks, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single commitBlockList(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @BodyParam("application/xml; charset=utf-8") BlockLookupList blocks, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @GET("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getBlockList(@HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("blocklisttype") BlockListType listType, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single getBlockList(Context context, @HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("blocklisttype") BlockListType listType, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId); } /** * The Upload Block Blob operation updates the content of an existing block blob. Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported with Put Blob; the content of the existing blob is overwritten with the content of the new blob. To perform a partial update of the content of a block blob, use the Put Block List operation. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void upload(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - uploadAsync(body, contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void upload(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + uploadAsync(context, body, contentLength, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Upload Block Blob operation updates the content of an existing block blob. Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported with Put Blob; the content of the existing blob is overwritten with the content of the new blob. To perform a partial update of the content of a block blob, use the Put Block List operation. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture uploadAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(uploadAsync(body, contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture uploadAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(uploadAsync(context, body, contentLength, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Upload Block Blob operation updates the content of an existing block blob. Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported with Put Blob; the content of the existing blob is overwritten with the content of the new blob. To perform a partial update of the content of a block blob, use the Put Block List operation. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single uploadWithRestResponseAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single uploadWithRestResponseAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -189,7 +172,54 @@ public Single uploadWithRestResponseAsync(@NonNull Flow throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(metadata); + Validator.validate(blobHTTPHeaders); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String blobType = "BlockBlob"; + String blobContentType = null; + if (blobHTTPHeaders != null) { + blobContentType = blobHTTPHeaders.blobContentType(); + } + String blobContentEncoding = null; + if (blobHTTPHeaders != null) { + blobContentEncoding = blobHTTPHeaders.blobContentEncoding(); + } + String blobContentLanguage = null; + if (blobHTTPHeaders != null) { + blobContentLanguage = blobHTTPHeaders.blobContentLanguage(); + } + byte[] blobContentMD5 = null; + if (blobHTTPHeaders != null) { + blobContentMD5 = blobHTTPHeaders.blobContentMD5(); + } + String blobCacheControl = null; + if (blobHTTPHeaders != null) { + blobCacheControl = blobHTTPHeaders.blobCacheControl(); + } + String blobContentDisposition = null; + if (blobHTTPHeaders != null) { + blobContentDisposition = blobHTTPHeaders.blobContentDisposition(); + } + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } String blobContentMD5Converted = Base64Util.encodeToString(blobContentMD5); DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { @@ -199,83 +229,82 @@ public Single uploadWithRestResponseAsync(@NonNull Flow if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.upload(this.client.url(), body, timeout, contentLength, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, blobType); + return service.upload(context, this.client.url(), body, timeout, contentLength, metadata, this.client.version(), requestId, blobType, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, blobCacheControl, blobContentDisposition, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Upload Block Blob operation updates the content of an existing block blob. Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not supported with Put Blob; the content of the existing blob is overwritten with the content of the new blob. To perform a partial update of the content of a block blob, use the Put Block List operation. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable uploadAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return uploadWithRestResponseAsync(body, contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable uploadAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return uploadWithRestResponseAsync(context, body, contentLength, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Stage Block operation creates a new block to be committed as part of a blob. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. * @param body Initial data. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void stageBlock(@NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, Integer timeout, String leaseId, String requestId) { - stageBlockAsync(blockId, contentLength, body, timeout, leaseId, requestId).blockingAwait(); + public void stageBlock(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, byte[] transactionalContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + stageBlockAsync(context, blockId, contentLength, body, transactionalContentMD5, timeout, requestId, leaseAccessConditions).blockingAwait(); } /** * The Stage Block operation creates a new block to be committed as part of a blob. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. * @param body Initial data. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture stageBlockAsync(@NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, Integer timeout, String leaseId, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(stageBlockAsync(blockId, contentLength, body, timeout, leaseId, requestId), serviceCallback); + public ServiceFuture stageBlockAsync(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, byte[] transactionalContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(stageBlockAsync(context, blockId, contentLength, body, transactionalContentMD5, timeout, requestId, leaseAccessConditions), serviceCallback); } /** * The Stage Block operation creates a new block to be committed as part of a blob. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. * @param body Initial data. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single stageBlockWithRestResponseAsync(@NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, Integer timeout, String leaseId, String requestId) { + public Single stageBlockWithRestResponseAsync(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, byte[] transactionalContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -288,80 +317,91 @@ public Single stageBlockWithRestResponseAsync(@NonN if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); final String comp = "block"; - return service.stageBlock(this.client.url(), blockId, contentLength, body, timeout, leaseId, this.client.version(), requestId, comp); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + String transactionalContentMD5Converted = Base64Util.encodeToString(transactionalContentMD5); + return service.stageBlock(context, this.client.url(), blockId, contentLength, transactionalContentMD5Converted, body, timeout, this.client.version(), requestId, comp, leaseId); } /** * The Stage Block operation creates a new block to be committed as part of a blob. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. * @param body Initial data. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable stageBlockAsync(@NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, Integer timeout, String leaseId, String requestId) { - return stageBlockWithRestResponseAsync(blockId, contentLength, body, timeout, leaseId, requestId) + public Completable stageBlockAsync(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull Flowable body, byte[] transactionalContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return stageBlockWithRestResponseAsync(context, blockId, contentLength, body, transactionalContentMD5, timeout, requestId, leaseAccessConditions) .toCompletable(); } /** * The Stage Block operation creates a new block to be committed as part of a blob where the contents are read from a URL. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. - * @param sourceUrl Specifiy an URL to the copy source. + * @param sourceUrl Specify a URL to the copy source. * @param sourceRange Bytes of source data in the specified range. * @param sourceContentMD5 Specify the md5 calculated for the range of bytes that must be read from the copy source. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void stageBlockFromURL(@NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String leaseId, String requestId) { - stageBlockFromURLAsync(blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5, timeout, leaseId, requestId).blockingAwait(); + public void stageBlockFromURL(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + stageBlockFromURLAsync(context, blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5, timeout, requestId, leaseAccessConditions).blockingAwait(); } /** * The Stage Block operation creates a new block to be committed as part of a blob where the contents are read from a URL. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. - * @param sourceUrl Specifiy an URL to the copy source. + * @param sourceUrl Specify a URL to the copy source. * @param sourceRange Bytes of source data in the specified range. * @param sourceContentMD5 Specify the md5 calculated for the range of bytes that must be read from the copy source. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture stageBlockFromURLAsync(@NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String leaseId, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(stageBlockFromURLAsync(blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5, timeout, leaseId, requestId), serviceCallback); + public ServiceFuture stageBlockFromURLAsync(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(stageBlockFromURLAsync(context, blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5, timeout, requestId, leaseAccessConditions), serviceCallback); } /** * The Stage Block operation creates a new block to be committed as part of a blob where the contents are read from a URL. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. - * @param sourceUrl Specifiy an URL to the copy source. + * @param sourceUrl Specify a URL to the copy source. * @param sourceRange Bytes of source data in the specified range. * @param sourceContentMD5 Specify the md5 calculated for the range of bytes that must be read from the copy source. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single stageBlockFromURLWithRestResponseAsync(@NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String leaseId, String requestId) { + public Single stageBlockFromURLWithRestResponseAsync(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -375,104 +415,89 @@ public Single stageBlockFromURLWithRestRespo throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(sourceUrl); + Validator.validate(leaseAccessConditions); final String comp = "block"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } String sourceContentMD5Converted = Base64Util.encodeToString(sourceContentMD5); - return service.stageBlockFromURL(this.client.url(), blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5Converted, timeout, leaseId, this.client.version(), requestId, comp); + return service.stageBlockFromURL(context, this.client.url(), blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5Converted, timeout, this.client.version(), requestId, comp, leaseId); } /** * The Stage Block operation creates a new block to be committed as part of a blob where the contents are read from a URL. * + * @param context The context to associate with this operation. * @param blockId A valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for each block. * @param contentLength The length of the request. - * @param sourceUrl Specifiy an URL to the copy source. + * @param sourceUrl Specify a URL to the copy source. * @param sourceRange Bytes of source data in the specified range. * @param sourceContentMD5 Specify the md5 calculated for the range of bytes that must be read from the copy source. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable stageBlockFromURLAsync(@NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String leaseId, String requestId) { - return stageBlockFromURLWithRestResponseAsync(blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5, timeout, leaseId, requestId) + public Completable stageBlockFromURLAsync(Context context, @NonNull String blockId, @NonNull long contentLength, @NonNull URL sourceUrl, String sourceRange, byte[] sourceContentMD5, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return stageBlockFromURLWithRestResponseAsync(context, blockId, contentLength, sourceUrl, sourceRange, sourceContentMD5, timeout, requestId, leaseAccessConditions) .toCompletable(); } /** * The Commit Block List operation writes a blob by specifying the list of block IDs that make up the blob. In order to be written as part of a blob, a block must have been successfully written to the server in a prior Put Block operation. You can call Put Block List to update a blob by uploading only those blocks that have changed, then committing the new and existing blocks together. You can do this by specifying whether to commit a block from the committed block list or from the uncommitted block list, or to commit the most recently uploaded version of the block, whichever list it may belong to. * + * @param context The context to associate with this operation. * @param blocks the BlockLookupList value. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void commitBlockList(@NonNull BlockLookupList blocks, Integer timeout, String blobCacheControl, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - commitBlockListAsync(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void commitBlockList(Context context, @NonNull BlockLookupList blocks, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + commitBlockListAsync(context, blocks, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Commit Block List operation writes a blob by specifying the list of block IDs that make up the blob. In order to be written as part of a blob, a block must have been successfully written to the server in a prior Put Block operation. You can call Put Block List to update a blob by uploading only those blocks that have changed, then committing the new and existing blocks together. You can do this by specifying whether to commit a block from the committed block list or from the uncommitted block list, or to commit the most recently uploaded version of the block, whichever list it may belong to. * + * @param context The context to associate with this operation. * @param blocks the BlockLookupList value. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture commitBlockListAsync(@NonNull BlockLookupList blocks, Integer timeout, String blobCacheControl, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(commitBlockListAsync(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture commitBlockListAsync(Context context, @NonNull BlockLookupList blocks, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(commitBlockListAsync(context, blocks, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Commit Block List operation writes a blob by specifying the list of block IDs that make up the blob. In order to be written as part of a blob, a block must have been successfully written to the server in a prior Put Block operation. You can call Put Block List to update a blob by uploading only those blocks that have changed, then committing the new and existing blocks together. You can do this by specifying whether to commit a block from the committed block list or from the uncommitted block list, or to commit the most recently uploaded version of the block, whichever list it may belong to. * + * @param context The context to associate with this operation. * @param blocks the BlockLookupList value. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single commitBlockListWithRestResponseAsync(@NonNull BlockLookupList blocks, Integer timeout, String blobCacheControl, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single commitBlockListWithRestResponseAsync(Context context, @NonNull BlockLookupList blocks, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -484,7 +509,54 @@ public Single commitBlockListWithRestResponseA } Validator.validate(metadata); Validator.validate(blocks); + Validator.validate(blobHTTPHeaders); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "blocklist"; + String blobCacheControl = null; + if (blobHTTPHeaders != null) { + blobCacheControl = blobHTTPHeaders.blobCacheControl(); + } + String blobContentType = null; + if (blobHTTPHeaders != null) { + blobContentType = blobHTTPHeaders.blobContentType(); + } + String blobContentEncoding = null; + if (blobHTTPHeaders != null) { + blobContentEncoding = blobHTTPHeaders.blobContentEncoding(); + } + String blobContentLanguage = null; + if (blobHTTPHeaders != null) { + blobContentLanguage = blobHTTPHeaders.blobContentLanguage(); + } + byte[] blobContentMD5 = null; + if (blobHTTPHeaders != null) { + blobContentMD5 = blobHTTPHeaders.blobContentMD5(); + } + String blobContentDisposition = null; + if (blobHTTPHeaders != null) { + blobContentDisposition = blobHTTPHeaders.blobContentDisposition(); + } + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } String blobContentMD5Converted = Base64Util.encodeToString(blobContentMD5); DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { @@ -494,80 +566,76 @@ public Single commitBlockListWithRestResponseA if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.commitBlockList(this.client.url(), timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, metadata, leaseId, blobContentDisposition, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, blocks, this.client.version(), requestId, comp); + return service.commitBlockList(context, this.client.url(), timeout, metadata, blocks, this.client.version(), requestId, comp, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, blobContentDisposition, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Commit Block List operation writes a blob by specifying the list of block IDs that make up the blob. In order to be written as part of a blob, a block must have been successfully written to the server in a prior Put Block operation. You can call Put Block List to update a blob by uploading only those blocks that have changed, then committing the new and existing blocks together. You can do this by specifying whether to commit a block from the committed block list or from the uncommitted block list, or to commit the most recently uploaded version of the block, whichever list it may belong to. * + * @param context The context to associate with this operation. * @param blocks the BlockLookupList value. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable commitBlockListAsync(@NonNull BlockLookupList blocks, Integer timeout, String blobCacheControl, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return commitBlockListWithRestResponseAsync(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable commitBlockListAsync(Context context, @NonNull BlockLookupList blocks, Integer timeout, Map metadata, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return commitBlockListWithRestResponseAsync(context, blocks, timeout, metadata, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Get Block List operation retrieves the list of blocks that have been uploaded as part of a block blob. * + * @param context The context to associate with this operation. * @param listType Specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists together. Possible values include: 'committed', 'uncommitted', 'all'. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the BlockList object if successful. */ - public BlockList getBlockList(@NonNull BlockListType listType, String snapshot, Integer timeout, String leaseId, String requestId) { - return getBlockListAsync(listType, snapshot, timeout, leaseId, requestId).blockingGet(); + public BlockList getBlockList(Context context, @NonNull BlockListType listType, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return getBlockListAsync(context, listType, snapshot, timeout, requestId, leaseAccessConditions).blockingGet(); } /** * The Get Block List operation retrieves the list of blocks that have been uploaded as part of a block blob. * + * @param context The context to associate with this operation. * @param listType Specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists together. Possible values include: 'committed', 'uncommitted', 'all'. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getBlockListAsync(@NonNull BlockListType listType, String snapshot, Integer timeout, String leaseId, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getBlockListAsync(listType, snapshot, timeout, leaseId, requestId), serviceCallback); + public ServiceFuture getBlockListAsync(Context context, @NonNull BlockListType listType, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getBlockListAsync(context, listType, snapshot, timeout, requestId, leaseAccessConditions), serviceCallback); } /** * The Get Block List operation retrieves the list of blocks that have been uploaded as part of a block blob. * + * @param context The context to associate with this operation. * @param listType Specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists together. Possible values include: 'committed', 'uncommitted', 'all'. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getBlockListWithRestResponseAsync(@NonNull BlockListType listType, String snapshot, Integer timeout, String leaseId, String requestId) { + public Single getBlockListWithRestResponseAsync(Context context, @NonNull BlockListType listType, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -577,23 +645,29 @@ public Single getBlockListWithRestResponseAsync(@ if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); final String comp = "blocklist"; - return service.getBlockList(this.client.url(), snapshot, listType, timeout, leaseId, this.client.version(), requestId, comp); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + return service.getBlockList(context, this.client.url(), snapshot, listType, timeout, this.client.version(), requestId, comp, leaseId); } /** * The Get Block List operation retrieves the list of blocks that have been uploaded as part of a block blob. * + * @param context The context to associate with this operation. * @param listType Specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists together. Possible values include: 'committed', 'uncommitted', 'all'. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe getBlockListAsync(@NonNull BlockListType listType, String snapshot, Integer timeout, String leaseId, String requestId) { - return getBlockListWithRestResponseAsync(listType, snapshot, timeout, leaseId, requestId) + public Maybe getBlockListAsync(Context context, @NonNull BlockListType listType, String snapshot, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return getBlockListWithRestResponseAsync(context, listType, snapshot, timeout, requestId, leaseAccessConditions) .flatMapMaybe((BlockBlobGetBlockListResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } } diff --git a/src/main/java/com/microsoft/azure/storage/GeneratedContainers.java b/src/main/java/com/microsoft/azure/storage/GeneratedContainers.java index e996745c7f80..132cee3f080f 100644 --- a/src/main/java/com/microsoft/azure/storage/GeneratedContainers.java +++ b/src/main/java/com/microsoft/azure/storage/GeneratedContainers.java @@ -25,13 +25,16 @@ import com.microsoft.azure.storage.blob.models.ContainerRenewLeaseResponse; import com.microsoft.azure.storage.blob.models.ContainerSetAccessPolicyResponse; import com.microsoft.azure.storage.blob.models.ContainerSetMetadataResponse; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; import com.microsoft.azure.storage.blob.models.ListBlobsFlatSegmentResponse; import com.microsoft.azure.storage.blob.models.ListBlobsHierarchySegmentResponse; import com.microsoft.azure.storage.blob.models.ListBlobsIncludeItem; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; import com.microsoft.azure.storage.blob.models.PublicAccessType; import com.microsoft.azure.storage.blob.models.SignedIdentifier; import com.microsoft.azure.storage.blob.models.StorageErrorException; import com.microsoft.rest.v2.CollectionFormat; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.DateTimeRfc1123; import com.microsoft.rest.v2.RestProxy; import com.microsoft.rest.v2.ServiceCallback; @@ -51,6 +54,7 @@ import io.reactivex.Maybe; import io.reactivex.Single; import io.reactivex.annotations.NonNull; + import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.HashMap; @@ -91,77 +95,78 @@ private interface ContainersService { @PUT("{containerName}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single create(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-blob-public-access") PublicAccessType access, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype); + Single create(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-blob-public-access") PublicAccessType access, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype); @GET("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getProperties(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype); + Single getProperties(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-id") String leaseId); @DELETE("{containerName}") @ExpectedResponses({202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single delete(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype); + Single delete(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince); @PUT("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single setMetadata(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single setMetadata(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince); @GET("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getAccessPolicy(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single getAccessPolicy(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId); @PUT("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single setAccessPolicy(@HostParam("url") String url, @BodyParam("application/xml; charset=utf-8") SignedIdentifiersWrapper containerAcl, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-blob-public-access") PublicAccessType access, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single setAccessPolicy(Context context, @HostParam("url") String url, @BodyParam("application/xml; charset=utf-8") SignedIdentifiersWrapper containerAcl, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-blob-public-access") PublicAccessType access, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince); @PUT("{containerName}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single acquireLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-duration") Integer duration, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action); + Single acquireLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-duration") Integer duration, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince); @PUT("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single releaseLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action); + Single releaseLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince); @PUT("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single renewLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action); + Single renewLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince); @PUT("{containerName}") @ExpectedResponses({202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single breakLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-break-period") Integer breakPeriod, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action); + Single breakLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-break-period") Integer breakPeriod, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince); @PUT("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single changeLease(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action); + Single changeLease(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-proposed-lease-id") String proposedLeaseId, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @QueryParam("restype") String restype, @HeaderParam("x-ms-lease-action") String action, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince); @GET("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single listBlobFlatSegment(@HostParam("url") String url, @QueryParam("prefix") String prefix, @QueryParam("marker") String marker, @QueryParam("maxresults") Integer maxresults, @QueryParam("include") String include, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single listBlobFlatSegment(Context context, @HostParam("url") String url, @QueryParam("prefix") String prefix, @QueryParam("marker") String marker, @QueryParam("maxresults") Integer maxresults, @QueryParam("include") String include, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); @GET("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single listBlobHierarchySegment(@HostParam("url") String url, @QueryParam("prefix") String prefix, @QueryParam("delimiter") String delimiter, @QueryParam("marker") String marker, @QueryParam("maxresults") Integer maxresults, @QueryParam("include") String include, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single listBlobHierarchySegment(Context context, @HostParam("url") String url, @QueryParam("prefix") String prefix, @QueryParam("delimiter") String delimiter, @QueryParam("marker") String marker, @QueryParam("maxresults") Integer maxresults, @QueryParam("include") String include, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); @GET("{containerName}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getAccountInfo(@HostParam("url") String url, @HeaderParam("x-ms-version") String version, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single getAccountInfo(Context context, @HostParam("url") String url, @HeaderParam("x-ms-version") String version, @QueryParam("restype") String restype, @QueryParam("comp") String comp); } /** * creates a new container under the specified account. If the container with the same name already exists, the operation fails. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. @@ -170,13 +175,14 @@ private interface ContainersService { * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void create(Integer timeout, Map metadata, PublicAccessType access, String requestId) { - createAsync(timeout, metadata, access, requestId).blockingAwait(); + public void create(Context context, Integer timeout, Map metadata, PublicAccessType access, String requestId) { + createAsync(context, timeout, metadata, access, requestId).blockingAwait(); } /** * creates a new container under the specified account. If the container with the same name already exists, the operation fails. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. @@ -185,13 +191,14 @@ public void create(Integer timeout, Map metadata, PublicAccessTy * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture createAsync(Integer timeout, Map metadata, PublicAccessType access, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(createAsync(timeout, metadata, access, requestId), serviceCallback); + public ServiceFuture createAsync(Context context, Integer timeout, Map metadata, PublicAccessType access, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(createAsync(context, timeout, metadata, access, requestId), serviceCallback); } /** * creates a new container under the specified account. If the container with the same name already exists, the operation fails. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. @@ -199,7 +206,7 @@ public ServiceFuture createAsync(Integer timeout, Map meta * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single createWithRestResponseAsync(Integer timeout, Map metadata, PublicAccessType access, String requestId) { + public Single createWithRestResponseAsync(Context context, Integer timeout, Map metadata, PublicAccessType access, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -208,12 +215,13 @@ public Single createWithRestResponseAsync(Integer timeo } Validator.validate(metadata); final String restype = "container"; - return service.create(this.client.url(), timeout, metadata, access, this.client.version(), requestId, restype); + return service.create(context, this.client.url(), timeout, metadata, access, this.client.version(), requestId, restype); } /** * creates a new container under the specified account. If the container with the same name already exists, the operation fails. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. @@ -221,124 +229,147 @@ public Single createWithRestResponseAsync(Integer timeo * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable createAsync(Integer timeout, Map metadata, PublicAccessType access, String requestId) { - return createWithRestResponseAsync(timeout, metadata, access, requestId) + public Completable createAsync(Context context, Integer timeout, Map metadata, PublicAccessType access, String requestId) { + return createWithRestResponseAsync(context, timeout, metadata, access, requestId) .toCompletable(); } /** * returns all user-defined metadata and system properties for the specified container. The data returned does not include the container's list of blobs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void getProperties(Integer timeout, String leaseId, String requestId) { - getPropertiesAsync(timeout, leaseId, requestId).blockingAwait(); + public void getProperties(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + getPropertiesAsync(context, timeout, requestId, leaseAccessConditions).blockingAwait(); } /** * returns all user-defined metadata and system properties for the specified container. The data returned does not include the container's list of blobs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getPropertiesAsync(Integer timeout, String leaseId, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getPropertiesAsync(timeout, leaseId, requestId), serviceCallback); + public ServiceFuture getPropertiesAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getPropertiesAsync(context, timeout, requestId, leaseAccessConditions), serviceCallback); } /** * returns all user-defined metadata and system properties for the specified container. The data returned does not include the container's list of blobs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getPropertiesWithRestResponseAsync(Integer timeout, String leaseId, String requestId) { + public Single getPropertiesWithRestResponseAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); final String restype = "container"; - return service.getProperties(this.client.url(), timeout, leaseId, this.client.version(), requestId, restype); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + return service.getProperties(context, this.client.url(), timeout, this.client.version(), requestId, restype, leaseId); } /** * returns all user-defined metadata and system properties for the specified container. The data returned does not include the container's list of blobs. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable getPropertiesAsync(Integer timeout, String leaseId, String requestId) { - return getPropertiesWithRestResponseAsync(timeout, leaseId, requestId) + public Completable getPropertiesAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return getPropertiesWithRestResponseAsync(context, timeout, requestId, leaseAccessConditions) .toCompletable(); } /** * operation marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void delete(Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - deleteAsync(timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, requestId).blockingAwait(); + public void delete(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + deleteAsync(context, timeout, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * operation marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture deleteAsync(Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(deleteAsync(timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, requestId), serviceCallback); + public ServiceFuture deleteAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(deleteAsync(context, timeout, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * operation marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single deleteWithRestResponseAsync(Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { + public Single deleteWithRestResponseAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String restype = "container"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -347,69 +378,72 @@ public Single deleteWithRestResponseAsync(Integer timeo if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.delete(this.client.url(), timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, this.client.version(), requestId, restype); + return service.delete(context, this.client.url(), timeout, this.client.version(), requestId, restype, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted); } /** * operation marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable deleteAsync(Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - return deleteWithRestResponseAsync(timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, requestId) + public Completable deleteAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return deleteWithRestResponseAsync(context, timeout, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * operation sets one or more user-defined name-value pairs for the specified container. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void setMetadata(Integer timeout, String leaseId, Map metadata, OffsetDateTime ifModifiedSince, String requestId) { - setMetadataAsync(timeout, leaseId, metadata, ifModifiedSince, requestId).blockingAwait(); + public void setMetadata(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + setMetadataAsync(context, timeout, metadata, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * operation sets one or more user-defined name-value pairs for the specified container. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture setMetadataAsync(Integer timeout, String leaseId, Map metadata, OffsetDateTime ifModifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(setMetadataAsync(timeout, leaseId, metadata, ifModifiedSince, requestId), serviceCallback); + public ServiceFuture setMetadataAsync(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(setMetadataAsync(context, timeout, metadata, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * operation sets one or more user-defined name-value pairs for the specified container. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single setMetadataWithRestResponseAsync(Integer timeout, String leaseId, Map metadata, OffsetDateTime ifModifiedSince, String requestId) { + public Single setMetadataWithRestResponseAsync(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -417,145 +451,165 @@ public Single setMetadataWithRestResponseAsync(Int throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(metadata); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String restype = "container"; final String comp = "metadata"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); } - return service.setMetadata(this.client.url(), timeout, leaseId, metadata, ifModifiedSinceConverted, this.client.version(), requestId, restype, comp); + return service.setMetadata(context, this.client.url(), timeout, metadata, this.client.version(), requestId, restype, comp, leaseId, ifModifiedSinceConverted); } /** * operation sets one or more user-defined name-value pairs for the specified container. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable setMetadataAsync(Integer timeout, String leaseId, Map metadata, OffsetDateTime ifModifiedSince, String requestId) { - return setMetadataWithRestResponseAsync(timeout, leaseId, metadata, ifModifiedSince, requestId) + public Completable setMetadataAsync(Context context, Integer timeout, Map metadata, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return setMetadataWithRestResponseAsync(context, timeout, metadata, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * gets the permissions for the specified container. The permissions indicate whether container data may be accessed publicly. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the List<SignedIdentifier> object if successful. */ - public List getAccessPolicy(Integer timeout, String leaseId, String requestId) { - return getAccessPolicyAsync(timeout, leaseId, requestId).blockingGet(); + public List getAccessPolicy(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return getAccessPolicyAsync(context, timeout, requestId, leaseAccessConditions).blockingGet(); } /** * gets the permissions for the specified container. The permissions indicate whether container data may be accessed publicly. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture> getAccessPolicyAsync(Integer timeout, String leaseId, String requestId, ServiceCallback> serviceCallback) { - return ServiceFuture.fromBody(getAccessPolicyAsync(timeout, leaseId, requestId), serviceCallback); + public ServiceFuture> getAccessPolicyAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ServiceCallback> serviceCallback) { + return ServiceFuture.fromBody(getAccessPolicyAsync(context, timeout, requestId, leaseAccessConditions), serviceCallback); } /** * gets the permissions for the specified container. The permissions indicate whether container data may be accessed publicly. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getAccessPolicyWithRestResponseAsync(Integer timeout, String leaseId, String requestId) { + public Single getAccessPolicyWithRestResponseAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); final String restype = "container"; final String comp = "acl"; - return service.getAccessPolicy(this.client.url(), timeout, leaseId, this.client.version(), requestId, restype, comp); + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + return service.getAccessPolicy(context, this.client.url(), timeout, this.client.version(), requestId, restype, comp, leaseId); } /** * gets the permissions for the specified container. The permissions indicate whether container data may be accessed publicly. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe> getAccessPolicyAsync(Integer timeout, String leaseId, String requestId) { - return getAccessPolicyWithRestResponseAsync(timeout, leaseId, requestId) + public Maybe> getAccessPolicyAsync(Context context, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions) { + return getAccessPolicyWithRestResponseAsync(context, timeout, requestId, leaseAccessConditions) .flatMapMaybe((ContainerGetAccessPolicyResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * sets the permissions for the specified container. The permissions indicate whether blobs in a container may be accessed publicly. * + * @param context The context to associate with this operation. * @param containerAcl the acls for the container. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void setAccessPolicy(List containerAcl, Integer timeout, String leaseId, PublicAccessType access, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - setAccessPolicyAsync(containerAcl, timeout, leaseId, access, ifModifiedSince, ifUnmodifiedSince, requestId).blockingAwait(); + public void setAccessPolicy(Context context, List containerAcl, Integer timeout, PublicAccessType access, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + setAccessPolicyAsync(context, containerAcl, timeout, access, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * sets the permissions for the specified container. The permissions indicate whether blobs in a container may be accessed publicly. * + * @param context The context to associate with this operation. * @param containerAcl the acls for the container. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture setAccessPolicyAsync(List containerAcl, Integer timeout, String leaseId, PublicAccessType access, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(setAccessPolicyAsync(containerAcl, timeout, leaseId, access, ifModifiedSince, ifUnmodifiedSince, requestId), serviceCallback); + public ServiceFuture setAccessPolicyAsync(Context context, List containerAcl, Integer timeout, PublicAccessType access, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(setAccessPolicyAsync(context, containerAcl, timeout, access, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * sets the permissions for the specified container. The permissions indicate whether blobs in a container may be accessed publicly. * + * @param context The context to associate with this operation. * @param containerAcl the acls for the container. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single setAccessPolicyWithRestResponseAsync(List containerAcl, Integer timeout, String leaseId, PublicAccessType access, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { + public Single setAccessPolicyWithRestResponseAsync(Context context, List containerAcl, Integer timeout, PublicAccessType access, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -563,8 +617,22 @@ public Single setAccessPolicyWithRestResponseA throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(containerAcl); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String restype = "container"; final String comp = "acl"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -573,83 +641,92 @@ public Single setAccessPolicyWithRestResponseA if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.setAccessPolicy(this.client.url(), new SignedIdentifiersWrapper(containerAcl), timeout, leaseId, access, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, this.client.version(), requestId, restype, comp); + return service.setAccessPolicy(context, this.client.url(), new SignedIdentifiersWrapper(containerAcl), timeout, access, this.client.version(), requestId, restype, comp, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted); } /** * sets the permissions for the specified container. The permissions indicate whether blobs in a container may be accessed publicly. * + * @param context The context to associate with this operation. * @param containerAcl the acls for the container. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. * @param access Specifies whether data in the container may be accessed publicly and the level of access. Possible values include: 'container', 'blob'. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable setAccessPolicyAsync(List containerAcl, Integer timeout, String leaseId, PublicAccessType access, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - return setAccessPolicyWithRestResponseAsync(containerAcl, timeout, leaseId, access, ifModifiedSince, ifUnmodifiedSince, requestId) + public Completable setAccessPolicyAsync(Context context, List containerAcl, Integer timeout, PublicAccessType access, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return setAccessPolicyWithRestResponseAsync(context, containerAcl, timeout, access, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void acquireLease(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - acquireLeaseAsync(timeout, duration, proposedLeaseId, ifModifiedSince, ifUnmodifiedSince, requestId).blockingAwait(); + public void acquireLease(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + acquireLeaseAsync(context, timeout, duration, proposedLeaseId, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture acquireLeaseAsync(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(acquireLeaseAsync(timeout, duration, proposedLeaseId, ifModifiedSince, ifUnmodifiedSince, requestId), serviceCallback); + public ServiceFuture acquireLeaseAsync(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(acquireLeaseAsync(context, timeout, duration, proposedLeaseId, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single acquireLeaseWithRestResponseAsync(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { + public Single acquireLeaseWithRestResponseAsync(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String restype = "container"; final String action = "acquire"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -658,70 +735,70 @@ public Single acquireLeaseWithRestResponseAsync(I if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.acquireLease(this.client.url(), timeout, duration, proposedLeaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, this.client.version(), requestId, comp, restype, action); + return service.acquireLease(context, this.client.url(), timeout, duration, proposedLeaseId, this.client.version(), requestId, comp, restype, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param duration Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable acquireLeaseAsync(Integer timeout, Integer duration, String proposedLeaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - return acquireLeaseWithRestResponseAsync(timeout, duration, proposedLeaseId, ifModifiedSince, ifUnmodifiedSince, requestId) + public Completable acquireLeaseAsync(Context context, Integer timeout, Integer duration, String proposedLeaseId, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return acquireLeaseWithRestResponseAsync(context, timeout, duration, proposedLeaseId, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void releaseLease(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - releaseLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId).blockingAwait(); + public void releaseLease(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + releaseLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture releaseLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(releaseLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId), serviceCallback); + public ServiceFuture releaseLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(releaseLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single releaseLeaseWithRestResponseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { + public Single releaseLeaseWithRestResponseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -731,9 +808,18 @@ public Single releaseLeaseWithRestResponseAsync(@ if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String restype = "container"; final String action = "release"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -742,69 +828,69 @@ public Single releaseLeaseWithRestResponseAsync(@ if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.releaseLease(this.client.url(), timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, this.client.version(), requestId, comp, restype, action); + return service.releaseLease(context, this.client.url(), timeout, leaseId, this.client.version(), requestId, comp, restype, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable releaseLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - return releaseLeaseWithRestResponseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId) + public Completable releaseLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return releaseLeaseWithRestResponseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void renewLease(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - renewLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId).blockingAwait(); + public void renewLease(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + renewLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture renewLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(renewLeaseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId), serviceCallback); + public ServiceFuture renewLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(renewLeaseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single renewLeaseWithRestResponseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { + public Single renewLeaseWithRestResponseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -814,9 +900,18 @@ public Single renewLeaseWithRestResponseAsync(@NonN if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String restype = "container"; final String action = "renew"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -825,78 +920,87 @@ public Single renewLeaseWithRestResponseAsync(@NonN if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.renewLease(this.client.url(), timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, this.client.version(), requestId, comp, restype, action); + return service.renewLease(context, this.client.url(), timeout, leaseId, this.client.version(), requestId, comp, restype, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable renewLeaseAsync(@NonNull String leaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - return renewLeaseWithRestResponseAsync(leaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId) + public Completable renewLeaseAsync(Context context, @NonNull String leaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return renewLeaseWithRestResponseAsync(context, leaseId, timeout, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void breakLease(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - breakLeaseAsync(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, requestId).blockingAwait(); + public void breakLease(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + breakLeaseAsync(context, timeout, breakPeriod, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture breakLeaseAsync(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(breakLeaseAsync(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, requestId), serviceCallback); + public ServiceFuture breakLeaseAsync(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(breakLeaseAsync(context, timeout, breakPeriod, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single breakLeaseWithRestResponseAsync(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { + public Single breakLeaseWithRestResponseAsync(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String restype = "container"; final String action = "break"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -905,72 +1009,72 @@ public Single breakLeaseWithRestResponseAsync(Integ if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.breakLease(this.client.url(), timeout, breakPeriod, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, this.client.version(), requestId, comp, restype, action); + return service.breakLease(context, this.client.url(), timeout, breakPeriod, this.client.version(), requestId, comp, restype, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param breakPeriod For a break operation, proposed duration the lease should continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available before the break period has expired, but the lease may be held for longer than the break period. If this header does not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an infinite lease breaks immediately. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable breakLeaseAsync(Integer timeout, Integer breakPeriod, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - return breakLeaseWithRestResponseAsync(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, requestId) + public Completable breakLeaseAsync(Context context, Integer timeout, Integer breakPeriod, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return breakLeaseWithRestResponseAsync(context, timeout, breakPeriod, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void changeLease(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - changeLeaseAsync(leaseId, proposedLeaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId).blockingAwait(); + public void changeLease(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + changeLeaseAsync(context, leaseId, proposedLeaseId, timeout, requestId, modifiedAccessConditions).blockingAwait(); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture changeLeaseAsync(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(changeLeaseAsync(leaseId, proposedLeaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId), serviceCallback); + public ServiceFuture changeLeaseAsync(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(changeLeaseAsync(context, leaseId, proposedLeaseId, timeout, requestId, modifiedAccessConditions), serviceCallback); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single changeLeaseWithRestResponseAsync(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { + public Single changeLeaseWithRestResponseAsync(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -983,9 +1087,18 @@ public Single changeLeaseWithRestResponseAsync(@No if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(modifiedAccessConditions); final String comp = "lease"; final String restype = "container"; final String action = "change"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -994,29 +1107,30 @@ public Single changeLeaseWithRestResponseAsync(@No if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.changeLease(this.client.url(), timeout, leaseId, proposedLeaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, this.client.version(), requestId, comp, restype, action); + return service.changeLease(context, this.client.url(), timeout, leaseId, proposedLeaseId, this.client.version(), requestId, comp, restype, action, ifModifiedSinceConverted, ifUnmodifiedSinceConverted); } /** * [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 to 60 seconds, or can be infinite. * - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. + * @param context The context to associate with this operation. + * @param leaseId Specifies the current lease ID on the resource. * @param proposedLeaseId Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string formats. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable changeLeaseAsync(@NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String requestId) { - return changeLeaseWithRestResponseAsync(leaseId, proposedLeaseId, timeout, ifModifiedSince, ifUnmodifiedSince, requestId) + public Completable changeLeaseAsync(Context context, @NonNull String leaseId, @NonNull String proposedLeaseId, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return changeLeaseWithRestResponseAsync(context, leaseId, proposedLeaseId, timeout, requestId, modifiedAccessConditions) .toCompletable(); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -1028,13 +1142,14 @@ public Completable changeLeaseAsync(@NonNull String leaseId, @NonNull String pro * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the ListBlobsFlatSegmentResponse object if successful. */ - public ListBlobsFlatSegmentResponse listBlobFlatSegment(String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { - return listBlobFlatSegmentAsync(prefix, marker, maxresults, include, timeout, requestId).blockingGet(); + public ListBlobsFlatSegmentResponse listBlobFlatSegment(Context context, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { + return listBlobFlatSegmentAsync(context, prefix, marker, maxresults, include, timeout, requestId).blockingGet(); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -1045,13 +1160,14 @@ public ListBlobsFlatSegmentResponse listBlobFlatSegment(String prefix, String ma * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture listBlobFlatSegmentAsync(String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(listBlobFlatSegmentAsync(prefix, marker, maxresults, include, timeout, requestId), serviceCallback); + public ServiceFuture listBlobFlatSegmentAsync(Context context, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(listBlobFlatSegmentAsync(context, prefix, marker, maxresults, include, timeout, requestId), serviceCallback); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -1061,7 +1177,7 @@ public ServiceFuture listBlobFlatSegmentAsync(Stri * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single listBlobFlatSegmentWithRestResponseAsync(String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { + public Single listBlobFlatSegmentWithRestResponseAsync(Context context, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1072,12 +1188,13 @@ public Single listBlobFlatSegmentWithRestR final String restype = "container"; final String comp = "list"; String includeConverted = this.client.serializerAdapter().serializeList(include, CollectionFormat.CSV); - return service.listBlobFlatSegment(this.client.url(), prefix, marker, maxresults, includeConverted, timeout, this.client.version(), requestId, restype, comp); + return service.listBlobFlatSegment(context, this.client.url(), prefix, marker, maxresults, includeConverted, timeout, this.client.version(), requestId, restype, comp); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -1087,14 +1204,15 @@ public Single listBlobFlatSegmentWithRestR * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe listBlobFlatSegmentAsync(String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { - return listBlobFlatSegmentWithRestResponseAsync(prefix, marker, maxresults, include, timeout, requestId) + public Maybe listBlobFlatSegmentAsync(Context context, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { + return listBlobFlatSegmentWithRestResponseAsync(context, prefix, marker, maxresults, include, timeout, requestId) .flatMapMaybe((ContainerListBlobFlatSegmentResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param delimiter When the request includes this parameter, the operation returns a BlobPrefix element in the response body that acts as a placeholder for all blobs whose names begin with the same substring up to the appearance of the delimiter character. The delimiter may be a single character or a string. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. @@ -1107,13 +1225,14 @@ public Maybe listBlobFlatSegmentAsync(String prefi * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the ListBlobsHierarchySegmentResponse object if successful. */ - public ListBlobsHierarchySegmentResponse listBlobHierarchySegment(@NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { - return listBlobHierarchySegmentAsync(delimiter, prefix, marker, maxresults, include, timeout, requestId).blockingGet(); + public ListBlobsHierarchySegmentResponse listBlobHierarchySegment(Context context, @NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { + return listBlobHierarchySegmentAsync(context, delimiter, prefix, marker, maxresults, include, timeout, requestId).blockingGet(); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param delimiter When the request includes this parameter, the operation returns a BlobPrefix element in the response body that acts as a placeholder for all blobs whose names begin with the same substring up to the appearance of the delimiter character. The delimiter may be a single character or a string. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. @@ -1125,13 +1244,14 @@ public ListBlobsHierarchySegmentResponse listBlobHierarchySegment(@NonNull Strin * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture listBlobHierarchySegmentAsync(@NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(listBlobHierarchySegmentAsync(delimiter, prefix, marker, maxresults, include, timeout, requestId), serviceCallback); + public ServiceFuture listBlobHierarchySegmentAsync(Context context, @NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(listBlobHierarchySegmentAsync(context, delimiter, prefix, marker, maxresults, include, timeout, requestId), serviceCallback); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param delimiter When the request includes this parameter, the operation returns a BlobPrefix element in the response body that acts as a placeholder for all blobs whose names begin with the same substring up to the appearance of the delimiter character. The delimiter may be a single character or a string. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. @@ -1142,7 +1262,7 @@ public ServiceFuture listBlobHierarchySegment * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single listBlobHierarchySegmentWithRestResponseAsync(@NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { + public Single listBlobHierarchySegmentWithRestResponseAsync(Context context, @NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1156,12 +1276,13 @@ public Single listBlobHierarchySegmen final String restype = "container"; final String comp = "list"; String includeConverted = this.client.serializerAdapter().serializeList(include, CollectionFormat.CSV); - return service.listBlobHierarchySegment(this.client.url(), prefix, delimiter, marker, maxresults, includeConverted, timeout, this.client.version(), requestId, restype, comp); + return service.listBlobHierarchySegment(context, this.client.url(), prefix, delimiter, marker, maxresults, includeConverted, timeout, this.client.version(), requestId, restype, comp); } /** * [Update] The List Blobs operation returns a list of the blobs under the specified container. * + * @param context The context to associate with this operation. * @param delimiter When the request includes this parameter, the operation returns a BlobPrefix element in the response body that acts as a placeholder for all blobs whose names begin with the same substring up to the appearance of the delimiter character. The delimiter may be a single character or a string. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. @@ -1172,38 +1293,43 @@ public Single listBlobHierarchySegmen * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe listBlobHierarchySegmentAsync(@NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { - return listBlobHierarchySegmentWithRestResponseAsync(delimiter, prefix, marker, maxresults, include, timeout, requestId) + public Maybe listBlobHierarchySegmentAsync(Context context, @NonNull String delimiter, String prefix, String marker, Integer maxresults, List include, Integer timeout, String requestId) { + return listBlobHierarchySegmentWithRestResponseAsync(context, delimiter, prefix, marker, maxresults, include, timeout, requestId) .flatMapMaybe((ContainerListBlobHierarchySegmentResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void getAccountInfo() { - getAccountInfoAsync().blockingAwait(); + public void getAccountInfo(Context context) { + getAccountInfoAsync(context).blockingAwait(); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getAccountInfoAsync(ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getAccountInfoAsync(), serviceCallback); + public ServiceFuture getAccountInfoAsync(Context context, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getAccountInfoAsync(context), serviceCallback); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getAccountInfoWithRestResponseAsync() { + public Single getAccountInfoWithRestResponseAsync(Context context) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -1212,16 +1338,18 @@ public Single getAccountInfoWithRestResponseAsy } final String restype = "account"; final String comp = "properties"; - return service.getAccountInfo(this.client.url(), this.client.version(), restype, comp); + return service.getAccountInfo(context, this.client.url(), this.client.version(), restype, comp); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable getAccountInfoAsync() { - return getAccountInfoWithRestResponseAsync() + public Completable getAccountInfoAsync(Context context) { + return getAccountInfoWithRestResponseAsync(context) .toCompletable(); } } diff --git a/src/main/java/com/microsoft/azure/storage/GeneratedPageBlobs.java b/src/main/java/com/microsoft/azure/storage/GeneratedPageBlobs.java index 2e4eb494046b..9e7a7594d536 100644 --- a/src/main/java/com/microsoft/azure/storage/GeneratedPageBlobs.java +++ b/src/main/java/com/microsoft/azure/storage/GeneratedPageBlobs.java @@ -10,6 +10,9 @@ package com.microsoft.azure.storage; +import com.microsoft.azure.storage.blob.models.BlobHTTPHeaders; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; import com.microsoft.azure.storage.blob.models.PageBlobClearPagesResponse; import com.microsoft.azure.storage.blob.models.PageBlobCopyIncrementalResponse; import com.microsoft.azure.storage.blob.models.PageBlobCreateResponse; @@ -19,8 +22,10 @@ import com.microsoft.azure.storage.blob.models.PageBlobUpdateSequenceNumberResponse; import com.microsoft.azure.storage.blob.models.PageBlobUploadPagesResponse; import com.microsoft.azure.storage.blob.models.PageList; +import com.microsoft.azure.storage.blob.models.SequenceNumberAccessConditions; import com.microsoft.azure.storage.blob.models.SequenceNumberActionType; import com.microsoft.azure.storage.blob.models.StorageErrorException; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.DateTimeRfc1123; import com.microsoft.rest.v2.RestProxy; import com.microsoft.rest.v2.ServiceCallback; @@ -81,124 +86,103 @@ private interface PageBlobsService { @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single create(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-blob-content-length") long blobContentLength, @HeaderParam("x-ms-blob-sequence-number") Long blobSequenceNumber, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-blob-type") String blobType); + Single create(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("Content-Length") long contentLength, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("x-ms-blob-content-length") long blobContentLength, @HeaderParam("x-ms-blob-sequence-number") Long blobSequenceNumber, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @HeaderParam("x-ms-blob-type") String blobType, @HeaderParam("x-ms-blob-content-type") String blobContentType, @HeaderParam("x-ms-blob-content-encoding") String blobContentEncoding, @HeaderParam("x-ms-blob-content-language") String blobContentLanguage, @HeaderParam("x-ms-blob-content-md5") String blobContentMD5, @HeaderParam("x-ms-blob-cache-control") String blobCacheControl, @HeaderParam("x-ms-blob-content-disposition") String blobContentDisposition, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single uploadPages(@HostParam("url") String url, @BodyParam("application/octet-stream") Flowable body, @HeaderParam("Content-Length") long contentLength, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-if-sequence-number-le") Long ifSequenceNumberLessThanOrEqualTo, @HeaderParam("x-ms-if-sequence-number-lt") Long ifSequenceNumberLessThan, @HeaderParam("x-ms-if-sequence-number-eq") Long ifSequenceNumberEqualTo, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-page-write") String pageWrite); + Single uploadPages(Context context, @HostParam("url") String url, @BodyParam("application/octet-stream") Flowable body, @HeaderParam("Content-Length") long contentLength, @HeaderParam("Content-MD5") String transactionalContentMD5, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-page-write") String pageWrite, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-if-sequence-number-le") Long ifSequenceNumberLessThanOrEqualTo, @HeaderParam("x-ms-if-sequence-number-lt") Long ifSequenceNumberLessThan, @HeaderParam("x-ms-if-sequence-number-eq") Long ifSequenceNumberEqualTo, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({201}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single clearPages(@HostParam("url") String url, @HeaderParam("Content-Length") long contentLength, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-if-sequence-number-le") Long ifSequenceNumberLessThanOrEqualTo, @HeaderParam("x-ms-if-sequence-number-lt") Long ifSequenceNumberLessThan, @HeaderParam("x-ms-if-sequence-number-eq") Long ifSequenceNumberEqualTo, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-page-write") String pageWrite); + Single clearPages(Context context, @HostParam("url") String url, @HeaderParam("Content-Length") long contentLength, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-page-write") String pageWrite, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("x-ms-if-sequence-number-le") Long ifSequenceNumberLessThanOrEqualTo, @HeaderParam("x-ms-if-sequence-number-lt") Long ifSequenceNumberLessThan, @HeaderParam("x-ms-if-sequence-number-eq") Long ifSequenceNumberEqualTo, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @GET("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getPageRanges(@HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single getPageRanges(Context context, @HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @GET("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getPageRangesDiff(@HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @QueryParam("prevsnapshot") String prevsnapshot, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single getPageRangesDiff(Context context, @HostParam("url") String url, @QueryParam("snapshot") String snapshot, @QueryParam("timeout") Integer timeout, @QueryParam("prevsnapshot") String prevsnapshot, @HeaderParam("x-ms-range") String range, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single resize(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-blob-content-length") long blobContentLength, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single resize(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-blob-content-length") long blobContentLength, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single updateSequenceNumber(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-sequence-number-action") SequenceNumberActionType sequenceNumberAction, @HeaderParam("x-ms-blob-sequence-number") Long blobSequenceNumber, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single updateSequenceNumber(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-sequence-number-action") SequenceNumberActionType sequenceNumberAction, @HeaderParam("x-ms-blob-sequence-number") Long blobSequenceNumber, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("x-ms-lease-id") String leaseId, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); @PUT("{containerName}/{blob}") @ExpectedResponses({202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single copyIncremental(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-meta-") Map metadata, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatches, @HeaderParam("If-None-Match") String ifNoneMatch, @HeaderParam("x-ms-copy-source") URL copySource, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single copyIncremental(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-copy-source") URL copySource, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp, @HeaderParam("If-Modified-Since") DateTimeRfc1123 ifModifiedSince, @HeaderParam("If-Unmodified-Since") DateTimeRfc1123 ifUnmodifiedSince, @HeaderParam("If-Match") String ifMatch, @HeaderParam("If-None-Match") String ifNoneMatch); } /** * The Create operation creates a new page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void create(@NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId) { - createAsync(contentLength, blobContentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestId).blockingAwait(); + public void create(Context context, @NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, Map metadata, Long blobSequenceNumber, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + createAsync(context, contentLength, blobContentLength, timeout, metadata, blobSequenceNumber, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Create operation creates a new page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture createAsync(@NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(createAsync(contentLength, blobContentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestId), serviceCallback); + public ServiceFuture createAsync(Context context, @NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, Map metadata, Long blobSequenceNumber, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(createAsync(context, contentLength, blobContentLength, timeout, metadata, blobSequenceNumber, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Create operation creates a new page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single createWithRestResponseAsync(@NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId) { + public Single createWithRestResponseAsync(Context context, @NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, Map metadata, Long blobSequenceNumber, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -206,7 +190,54 @@ public Single createWithRestResponseAsync(@NonNull long throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } Validator.validate(metadata); + Validator.validate(blobHTTPHeaders); + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String blobType = "PageBlob"; + String blobContentType = null; + if (blobHTTPHeaders != null) { + blobContentType = blobHTTPHeaders.blobContentType(); + } + String blobContentEncoding = null; + if (blobHTTPHeaders != null) { + blobContentEncoding = blobHTTPHeaders.blobContentEncoding(); + } + String blobContentLanguage = null; + if (blobHTTPHeaders != null) { + blobContentLanguage = blobHTTPHeaders.blobContentLanguage(); + } + byte[] blobContentMD5 = null; + if (blobHTTPHeaders != null) { + blobContentMD5 = blobHTTPHeaders.blobContentMD5(); + } + String blobCacheControl = null; + if (blobHTTPHeaders != null) { + blobCacheControl = blobHTTPHeaders.blobCacheControl(); + } + String blobContentDisposition = null; + if (blobHTTPHeaders != null) { + blobContentDisposition = blobHTTPHeaders.blobContentDisposition(); + } + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } String blobContentMD5Converted = Base64Util.encodeToString(blobContentMD5); DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { @@ -216,105 +247,89 @@ public Single createWithRestResponseAsync(@NonNull long if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.create(this.client.url(), timeout, contentLength, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, blobContentLength, blobSequenceNumber, this.client.version(), requestId, blobType); + return service.create(context, this.client.url(), timeout, contentLength, metadata, blobContentLength, blobSequenceNumber, this.client.version(), requestId, blobType, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5Converted, blobCacheControl, blobContentDisposition, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Create operation creates a new page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param blobContentType Optional. Sets the blob's content type. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentEncoding Optional. Sets the blob's content encoding. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentLanguage Optional. Set the blob's content language. If specified, this property is stored with the blob and returned with a read request. - * @param blobContentMD5 Optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. - * @param blobCacheControl Optional. Sets the blob's cache control. If specified, this property is stored with the blob and returned with a read request. * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param blobContentDisposition Optional. Sets the blob's Content-Disposition header. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param blobHTTPHeaders Additional parameters for the operation. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable createAsync(@NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, String blobContentType, String blobContentEncoding, String blobContentLanguage, byte[] blobContentMD5, String blobCacheControl, Map metadata, String leaseId, String blobContentDisposition, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId) { - return createWithRestResponseAsync(contentLength, blobContentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseId, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestId) + public Completable createAsync(Context context, @NonNull long contentLength, @NonNull long blobContentLength, Integer timeout, Map metadata, Long blobSequenceNumber, String requestId, BlobHTTPHeaders blobHTTPHeaders, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return createWithRestResponseAsync(context, contentLength, blobContentLength, timeout, metadata, blobSequenceNumber, requestId, blobHTTPHeaders, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Upload Pages operation writes a range of pages to a page blob. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void uploadPages(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - uploadPagesAsync(body, contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void uploadPages(Context context, @NonNull Flowable body, @NonNull long contentLength, byte[] transactionalContentMD5, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + uploadPagesAsync(context, body, contentLength, transactionalContentMD5, timeout, range, requestId, leaseAccessConditions, sequenceNumberAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Upload Pages operation writes a range of pages to a page blob. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture uploadPagesAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(uploadPagesAsync(body, contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture uploadPagesAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, byte[] transactionalContentMD5, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(uploadPagesAsync(context, body, contentLength, transactionalContentMD5, timeout, range, requestId, leaseAccessConditions, sequenceNumberAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Upload Pages operation writes a range of pages to a page blob. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single uploadPagesWithRestResponseAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single uploadPagesWithRestResponseAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, byte[] transactionalContentMD5, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -324,8 +339,44 @@ public Single uploadPagesWithRestResponseAsync(@Non if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(sequenceNumberAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "page"; final String pageWrite = "update"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + Long ifSequenceNumberLessThanOrEqualTo = null; + if (sequenceNumberAccessConditions != null) { + ifSequenceNumberLessThanOrEqualTo = sequenceNumberAccessConditions.ifSequenceNumberLessThanOrEqualTo(); + } + Long ifSequenceNumberLessThan = null; + if (sequenceNumberAccessConditions != null) { + ifSequenceNumberLessThan = sequenceNumberAccessConditions.ifSequenceNumberLessThan(); + } + Long ifSequenceNumberEqualTo = null; + if (sequenceNumberAccessConditions != null) { + ifSequenceNumberEqualTo = sequenceNumberAccessConditions.ifSequenceNumberEqualTo(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } + String transactionalContentMD5Converted = Base64Util.encodeToString(transactionalContentMD5); DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -334,106 +385,126 @@ public Single uploadPagesWithRestResponseAsync(@Non if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.uploadPages(this.client.url(), body, contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp, pageWrite); + return service.uploadPages(context, this.client.url(), body, contentLength, transactionalContentMD5Converted, timeout, range, this.client.version(), requestId, comp, pageWrite, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Upload Pages operation writes a range of pages to a page blob. * + * @param context The context to associate with this operation. * @param body Initial data. * @param contentLength The length of the request. + * @param transactionalContentMD5 Specify the transactional md5 for the body, to be validated by the service. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable uploadPagesAsync(@NonNull Flowable body, @NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return uploadPagesWithRestResponseAsync(body, contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable uploadPagesAsync(Context context, @NonNull Flowable body, @NonNull long contentLength, byte[] transactionalContentMD5, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return uploadPagesWithRestResponseAsync(context, body, contentLength, transactionalContentMD5, timeout, range, requestId, leaseAccessConditions, sequenceNumberAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Clear Pages operation clears a set of pages from a page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void clearPages(@NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - clearPagesAsync(contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void clearPages(Context context, @NonNull long contentLength, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + clearPagesAsync(context, contentLength, timeout, range, requestId, leaseAccessConditions, sequenceNumberAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * The Clear Pages operation clears a set of pages from a page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture clearPagesAsync(@NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(clearPagesAsync(contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture clearPagesAsync(Context context, @NonNull long contentLength, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(clearPagesAsync(context, contentLength, timeout, range, requestId, leaseAccessConditions, sequenceNumberAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Clear Pages operation clears a set of pages from a page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single clearPagesWithRestResponseAsync(@NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single clearPagesWithRestResponseAsync(Context context, @NonNull long contentLength, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(sequenceNumberAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "page"; final String pageWrite = "clear"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + Long ifSequenceNumberLessThanOrEqualTo = null; + if (sequenceNumberAccessConditions != null) { + ifSequenceNumberLessThanOrEqualTo = sequenceNumberAccessConditions.ifSequenceNumberLessThanOrEqualTo(); + } + Long ifSequenceNumberLessThan = null; + if (sequenceNumberAccessConditions != null) { + ifSequenceNumberLessThan = sequenceNumberAccessConditions.ifSequenceNumberLessThan(); + } + Long ifSequenceNumberEqualTo = null; + if (sequenceNumberAccessConditions != null) { + ifSequenceNumberEqualTo = sequenceNumberAccessConditions.ifSequenceNumberEqualTo(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -442,96 +513,108 @@ public Single clearPagesWithRestResponseAsync(@NonNu if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.clearPages(this.client.url(), contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp, pageWrite); + return service.clearPages(context, this.client.url(), contentLength, timeout, range, this.client.version(), requestId, comp, pageWrite, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Clear Pages operation clears a set of pages from a page blob. * + * @param context The context to associate with this operation. * @param contentLength The length of the request. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifSequenceNumberLessThanOrEqualTo Specify this header value to operate only on a blob if it has a sequence number less than or equal to the specified. - * @param ifSequenceNumberLessThan Specify this header value to operate only on a blob if it has a sequence number less than the specified. - * @param ifSequenceNumberEqualTo Specify this header value to operate only on a blob if it has the specified sequence number. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param sequenceNumberAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable clearPagesAsync(@NonNull long contentLength, Integer timeout, String range, String leaseId, Long ifSequenceNumberLessThanOrEqualTo, Long ifSequenceNumberLessThan, Long ifSequenceNumberEqualTo, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return clearPagesWithRestResponseAsync(contentLength, timeout, range, leaseId, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable clearPagesAsync(Context context, @NonNull long contentLength, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, SequenceNumberAccessConditions sequenceNumberAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return clearPagesWithRestResponseAsync(context, contentLength, timeout, range, requestId, leaseAccessConditions, sequenceNumberAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot of a page blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the PageList object if successful. */ - public PageList getPageRanges(String snapshot, Integer timeout, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return getPageRangesAsync(snapshot, timeout, range, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingGet(); + public PageList getPageRanges(Context context, String snapshot, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return getPageRangesAsync(context, snapshot, timeout, range, requestId, leaseAccessConditions, modifiedAccessConditions).blockingGet(); } /** * The Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot of a page blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getPageRangesAsync(String snapshot, Integer timeout, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getPageRangesAsync(snapshot, timeout, range, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture getPageRangesAsync(Context context, String snapshot, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getPageRangesAsync(context, snapshot, timeout, range, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * The Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot of a page blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getPageRangesWithRestResponseAsync(String snapshot, Integer timeout, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single getPageRangesWithRestResponseAsync(Context context, String snapshot, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "pagelist"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -540,96 +623,110 @@ public Single getPageRangesWithRestResponseAsync( if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.getPageRanges(this.client.url(), snapshot, timeout, range, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp); + return service.getPageRanges(context, this.client.url(), snapshot, timeout, range, this.client.version(), requestId, comp, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot of a page blob. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe getPageRangesAsync(String snapshot, Integer timeout, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return getPageRangesWithRestResponseAsync(snapshot, timeout, range, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Maybe getPageRangesAsync(Context context, String snapshot, Integer timeout, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return getPageRangesWithRestResponseAsync(context, snapshot, timeout, range, requestId, leaseAccessConditions, modifiedAccessConditions) .flatMapMaybe((PageBlobGetPageRangesResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * [Update] The Get Page Ranges Diff operation returns the list of valid page ranges for a page blob that were changed between target blob and previous snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param prevsnapshot Optional in version 2015-07-08 and newer. The prevsnapshot parameter is a DateTime value that specifies that the response will contain only pages that were changed between target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots are currently supported only for blobs created on or after January 1, 2016. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the PageList object if successful. */ - public PageList getPageRangesDiff(String snapshot, Integer timeout, String prevsnapshot, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return getPageRangesDiffAsync(snapshot, timeout, prevsnapshot, range, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingGet(); + public PageList getPageRangesDiff(Context context, String snapshot, Integer timeout, String prevsnapshot, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return getPageRangesDiffAsync(context, snapshot, timeout, prevsnapshot, range, requestId, leaseAccessConditions, modifiedAccessConditions).blockingGet(); } /** * [Update] The Get Page Ranges Diff operation returns the list of valid page ranges for a page blob that were changed between target blob and previous snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param prevsnapshot Optional in version 2015-07-08 and newer. The prevsnapshot parameter is a DateTime value that specifies that the response will contain only pages that were changed between target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots are currently supported only for blobs created on or after January 1, 2016. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getPageRangesDiffAsync(String snapshot, Integer timeout, String prevsnapshot, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getPageRangesDiffAsync(snapshot, timeout, prevsnapshot, range, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture getPageRangesDiffAsync(Context context, String snapshot, Integer timeout, String prevsnapshot, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getPageRangesDiffAsync(context, snapshot, timeout, prevsnapshot, range, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * [Update] The Get Page Ranges Diff operation returns the list of valid page ranges for a page blob that were changed between target blob and previous snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param prevsnapshot Optional in version 2015-07-08 and newer. The prevsnapshot parameter is a DateTime value that specifies that the response will contain only pages that were changed between target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots are currently supported only for blobs created on or after January 1, 2016. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getPageRangesDiffWithRestResponseAsync(String snapshot, Integer timeout, String prevsnapshot, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single getPageRangesDiffWithRestResponseAsync(Context context, String snapshot, Integer timeout, String prevsnapshot, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "pagelist"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -638,90 +735,104 @@ public Single getPageRangesDiffWithRestRespon if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.getPageRangesDiff(this.client.url(), snapshot, timeout, prevsnapshot, range, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, this.client.version(), requestId, comp); + return service.getPageRangesDiff(context, this.client.url(), snapshot, timeout, prevsnapshot, range, this.client.version(), requestId, comp, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * [Update] The Get Page Ranges Diff operation returns the list of valid page ranges for a page blob that were changed between target blob and previous snapshot. * + * @param context The context to associate with this operation. * @param snapshot The snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to retrieve. For more information on working with blob snapshots, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/creating-a-snapshot-of-a-blob">Creating a Snapshot of a Blob.</a>. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param prevsnapshot Optional in version 2015-07-08 and newer. The prevsnapshot parameter is a DateTime value that specifies that the response will contain only pages that were changed between target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots are currently supported only for blobs created on or after January 1, 2016. * @param range Return only the bytes of the blob in the specified range. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe getPageRangesDiffAsync(String snapshot, Integer timeout, String prevsnapshot, String range, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return getPageRangesDiffWithRestResponseAsync(snapshot, timeout, prevsnapshot, range, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Maybe getPageRangesDiffAsync(Context context, String snapshot, Integer timeout, String prevsnapshot, String range, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return getPageRangesDiffWithRestResponseAsync(context, snapshot, timeout, prevsnapshot, range, requestId, leaseAccessConditions, modifiedAccessConditions) .flatMapMaybe((PageBlobGetPageRangesDiffResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * Resize the Blob. * + * @param context The context to associate with this operation. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void resize(@NonNull long blobContentLength, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - resizeAsync(blobContentLength, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void resize(Context context, @NonNull long blobContentLength, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + resizeAsync(context, blobContentLength, timeout, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * Resize the Blob. * + * @param context The context to associate with this operation. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture resizeAsync(@NonNull long blobContentLength, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(resizeAsync(blobContentLength, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture resizeAsync(Context context, @NonNull long blobContentLength, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(resizeAsync(context, blobContentLength, timeout, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * Resize the Blob. * + * @param context The context to associate with this operation. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single resizeWithRestResponseAsync(@NonNull long blobContentLength, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single resizeWithRestResponseAsync(Context context, @NonNull long blobContentLength, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "properties"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -730,84 +841,76 @@ public Single resizeWithRestResponseAsync(@NonNull long if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.resize(this.client.url(), timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, blobContentLength, this.client.version(), requestId, comp); + return service.resize(context, this.client.url(), timeout, blobContentLength, this.client.version(), requestId, comp, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * Resize the Blob. * + * @param context The context to associate with this operation. * @param blobContentLength This header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte boundary. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable resizeAsync(@NonNull long blobContentLength, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return resizeWithRestResponseAsync(blobContentLength, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable resizeAsync(Context context, @NonNull long blobContentLength, Integer timeout, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return resizeWithRestResponseAsync(context, blobContentLength, timeout, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * Update the sequence number of the blob. * + * @param context The context to associate with this operation. * @param sequenceNumberAction Required if the x-ms-blob-sequence-number header is set for the request. This property applies to page blobs only. This property indicates how the service should modify the blob's sequence number. Possible values include: 'max', 'update', 'increment'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void updateSequenceNumber(@NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId) { - updateSequenceNumberAsync(sequenceNumberAction, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestId).blockingAwait(); + public void updateSequenceNumber(Context context, @NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, Long blobSequenceNumber, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + updateSequenceNumberAsync(context, sequenceNumberAction, timeout, blobSequenceNumber, requestId, leaseAccessConditions, modifiedAccessConditions).blockingAwait(); } /** * Update the sequence number of the blob. * + * @param context The context to associate with this operation. * @param sequenceNumberAction Required if the x-ms-blob-sequence-number header is set for the request. This property applies to page blobs only. This property indicates how the service should modify the blob's sequence number. Possible values include: 'max', 'update', 'increment'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture updateSequenceNumberAsync(@NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(updateSequenceNumberAsync(sequenceNumberAction, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestId), serviceCallback); + public ServiceFuture updateSequenceNumberAsync(Context context, @NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, Long blobSequenceNumber, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(updateSequenceNumberAsync(context, sequenceNumberAction, timeout, blobSequenceNumber, requestId, leaseAccessConditions, modifiedAccessConditions), serviceCallback); } /** * Update the sequence number of the blob. * + * @param context The context to associate with this operation. * @param sequenceNumberAction Required if the x-ms-blob-sequence-number header is set for the request. This property applies to page blobs only. This property indicates how the service should modify the blob's sequence number. Possible values include: 'max', 'update', 'increment'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single updateSequenceNumberWithRestResponseAsync(@NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId) { + public Single updateSequenceNumberWithRestResponseAsync(Context context, @NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, Long blobSequenceNumber, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -817,7 +920,29 @@ public Single updateSequenceNumberWithRest if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } + Validator.validate(leaseAccessConditions); + Validator.validate(modifiedAccessConditions); final String comp = "properties"; + String leaseId = null; + if (leaseAccessConditions != null) { + leaseId = leaseAccessConditions.leaseId(); + } + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -826,82 +951,71 @@ public Single updateSequenceNumberWithRest if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.updateSequenceNumber(this.client.url(), timeout, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, sequenceNumberAction, blobSequenceNumber, this.client.version(), requestId, comp); + return service.updateSequenceNumber(context, this.client.url(), timeout, sequenceNumberAction, blobSequenceNumber, this.client.version(), requestId, comp, leaseId, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * Update the sequence number of the blob. * + * @param context The context to associate with this operation. * @param sequenceNumberAction Required if the x-ms-blob-sequence-number header is set for the request. This property applies to page blobs only. This property indicates how the service should modify the blob's sequence number. Possible values include: 'max', 'update', 'increment'. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param leaseId If specified, the operation only succeeds if the container's lease is active and matches this ID. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param blobSequenceNumber Set for page blobs only. The sequence number is a user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param leaseAccessConditions Additional parameters for the operation. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable updateSequenceNumberAsync(@NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, String leaseId, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, Long blobSequenceNumber, String requestId) { - return updateSequenceNumberWithRestResponseAsync(sequenceNumberAction, timeout, leaseId, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestId) + public Completable updateSequenceNumberAsync(Context context, @NonNull SequenceNumberActionType sequenceNumberAction, Integer timeout, Long blobSequenceNumber, String requestId, LeaseAccessConditions leaseAccessConditions, ModifiedAccessConditions modifiedAccessConditions) { + return updateSequenceNumberWithRestResponseAsync(context, sequenceNumberAction, timeout, blobSequenceNumber, requestId, leaseAccessConditions, modifiedAccessConditions) .toCompletable(); } /** * The Copy Incremental operation copies a snapshot of the source page blob to a destination page blob. The snapshot is copied such that only the differential changes between the previously copied snapshot are transferred to the destination. The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. This API is supported since REST version 2016-05-31. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void copyIncremental(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - copyIncrementalAsync(copySource, timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId).blockingAwait(); + public void copyIncremental(Context context, @NonNull URL copySource, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + copyIncrementalAsync(context, copySource, timeout, requestId, modifiedAccessConditions).blockingAwait(); } /** * The Copy Incremental operation copies a snapshot of the source page blob to a destination page blob. The snapshot is copied such that only the differential changes between the previously copied snapshot are transferred to the destination. The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. This API is supported since REST version 2016-05-31. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture copyIncrementalAsync(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(copyIncrementalAsync(copySource, timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId), serviceCallback); + public ServiceFuture copyIncrementalAsync(Context context, @NonNull URL copySource, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(copyIncrementalAsync(context, copySource, timeout, requestId, modifiedAccessConditions), serviceCallback); } /** * The Copy Incremental operation copies a snapshot of the source page blob to a destination page blob. The snapshot is copied such that only the differential changes between the previously copied snapshot are transferred to the destination. The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. This API is supported since REST version 2016-05-31. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single copyIncrementalWithRestResponseAsync(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { + public Single copyIncrementalWithRestResponseAsync(Context context, @NonNull URL copySource, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -911,9 +1025,25 @@ public Single copyIncrementalWithRestResponseAs if (this.client.version() == null) { throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } - Validator.validate(metadata); Validator.validate(copySource); + Validator.validate(modifiedAccessConditions); final String comp = "incrementalcopy"; + OffsetDateTime ifModifiedSince = null; + if (modifiedAccessConditions != null) { + ifModifiedSince = modifiedAccessConditions.ifModifiedSince(); + } + OffsetDateTime ifUnmodifiedSince = null; + if (modifiedAccessConditions != null) { + ifUnmodifiedSince = modifiedAccessConditions.ifUnmodifiedSince(); + } + String ifMatch = null; + if (modifiedAccessConditions != null) { + ifMatch = modifiedAccessConditions.ifMatch(); + } + String ifNoneMatch = null; + if (modifiedAccessConditions != null) { + ifNoneMatch = modifiedAccessConditions.ifNoneMatch(); + } DateTimeRfc1123 ifModifiedSinceConverted = null; if (ifModifiedSince != null) { ifModifiedSinceConverted = new DateTimeRfc1123(ifModifiedSince); @@ -922,25 +1052,22 @@ public Single copyIncrementalWithRestResponseAs if (ifUnmodifiedSince != null) { ifUnmodifiedSinceConverted = new DateTimeRfc1123(ifUnmodifiedSince); } - return service.copyIncremental(this.client.url(), timeout, metadata, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatches, ifNoneMatch, copySource, this.client.version(), requestId, comp); + return service.copyIncremental(context, this.client.url(), timeout, copySource, this.client.version(), requestId, comp, ifModifiedSinceConverted, ifUnmodifiedSinceConverted, ifMatch, ifNoneMatch); } /** * The Copy Incremental operation copies a snapshot of the source page blob to a destination page blob. The snapshot is copied such that only the differential changes between the previously copied snapshot are transferred to the destination. The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. This API is supported since REST version 2016-05-31. * + * @param context The context to associate with this operation. * @param copySource Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must either be public or must be authenticated via a shared access signature. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. - * @param metadata Optional. Specifies a user-defined name-value pair associated with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and Metadata for more information. - * @param ifModifiedSince Specify this header value to operate only on a blob if it has been modified since the specified date/time. - * @param ifUnmodifiedSince Specify this header value to operate only on a blob if it has not been modified since the specified date/time. - * @param ifMatches Specify an ETag value to operate only on blobs with a matching value. - * @param ifNoneMatch Specify an ETag value to operate only on blobs without a matching value. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. + * @param modifiedAccessConditions Additional parameters for the operation. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable copyIncrementalAsync(@NonNull URL copySource, Integer timeout, Map metadata, OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, String ifMatches, String ifNoneMatch, String requestId) { - return copyIncrementalWithRestResponseAsync(copySource, timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestId) + public Completable copyIncrementalAsync(Context context, @NonNull URL copySource, Integer timeout, String requestId, ModifiedAccessConditions modifiedAccessConditions) { + return copyIncrementalWithRestResponseAsync(context, copySource, timeout, requestId, modifiedAccessConditions) .toCompletable(); } } diff --git a/src/main/java/com/microsoft/azure/storage/GeneratedServices.java b/src/main/java/com/microsoft/azure/storage/GeneratedServices.java index 4f56d62672c2..9399927fc07c 100644 --- a/src/main/java/com/microsoft/azure/storage/GeneratedServices.java +++ b/src/main/java/com/microsoft/azure/storage/GeneratedServices.java @@ -20,6 +20,7 @@ import com.microsoft.azure.storage.blob.models.StorageErrorException; import com.microsoft.azure.storage.blob.models.StorageServiceProperties; import com.microsoft.azure.storage.blob.models.StorageServiceStats; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.RestProxy; import com.microsoft.rest.v2.ServiceCallback; import com.microsoft.rest.v2.ServiceFuture; @@ -72,32 +73,33 @@ private interface ServicesService { @PUT("") @ExpectedResponses({202}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single setProperties(@HostParam("url") String url, @BodyParam("application/xml; charset=utf-8") StorageServiceProperties storageServiceProperties, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single setProperties(Context context, @HostParam("url") String url, @BodyParam("application/xml; charset=utf-8") StorageServiceProperties storageServiceProperties, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); @GET("") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getProperties(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single getProperties(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); @GET("") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getStatistics(@HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single getStatistics(Context context, @HostParam("url") String url, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("restype") String restype, @QueryParam("comp") String comp); @GET("") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single listContainersSegment(@HostParam("url") String url, @QueryParam("prefix") String prefix, @QueryParam("marker") String marker, @QueryParam("maxresults") Integer maxresults, @QueryParam("include") ListContainersIncludeType include, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); + Single listContainersSegment(Context context, @HostParam("url") String url, @QueryParam("prefix") String prefix, @QueryParam("marker") String marker, @QueryParam("maxresults") Integer maxresults, @QueryParam("include") ListContainersIncludeType include, @QueryParam("timeout") Integer timeout, @HeaderParam("x-ms-version") String version, @HeaderParam("x-ms-client-request-id") String requestId, @QueryParam("comp") String comp); @GET("") @ExpectedResponses({200}) @UnexpectedResponseExceptionType(StorageErrorException.class) - Single getAccountInfo(@HostParam("url") String url, @HeaderParam("x-ms-version") String version, @QueryParam("restype") String restype, @QueryParam("comp") String comp); + Single getAccountInfo(Context context, @HostParam("url") String url, @HeaderParam("x-ms-version") String version, @QueryParam("restype") String restype, @QueryParam("comp") String comp); } /** * Sets properties for a storage account's Blob service endpoint, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param storageServiceProperties The StorageService properties. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. @@ -105,13 +107,14 @@ private interface ServicesService { * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void setProperties(@NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId) { - setPropertiesAsync(storageServiceProperties, timeout, requestId).blockingAwait(); + public void setProperties(Context context, @NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId) { + setPropertiesAsync(context, storageServiceProperties, timeout, requestId).blockingAwait(); } /** * Sets properties for a storage account's Blob service endpoint, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param storageServiceProperties The StorageService properties. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. @@ -119,20 +122,21 @@ public void setProperties(@NonNull StorageServiceProperties storageServiceProper * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture setPropertiesAsync(@NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(setPropertiesAsync(storageServiceProperties, timeout, requestId), serviceCallback); + public ServiceFuture setPropertiesAsync(Context context, @NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(setPropertiesAsync(context, storageServiceProperties, timeout, requestId), serviceCallback); } /** * Sets properties for a storage account's Blob service endpoint, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param storageServiceProperties The StorageService properties. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single setPropertiesWithRestResponseAsync(@NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId) { + public Single setPropertiesWithRestResponseAsync(Context context, @NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -145,26 +149,28 @@ public Single setPropertiesWithRestResponseAsync(@ Validator.validate(storageServiceProperties); final String restype = "service"; final String comp = "properties"; - return service.setProperties(this.client.url(), storageServiceProperties, timeout, this.client.version(), requestId, restype, comp); + return service.setProperties(context, this.client.url(), storageServiceProperties, timeout, this.client.version(), requestId, restype, comp); } /** * Sets properties for a storage account's Blob service endpoint, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param storageServiceProperties The StorageService properties. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable setPropertiesAsync(@NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId) { - return setPropertiesWithRestResponseAsync(storageServiceProperties, timeout, requestId) + public Completable setPropertiesAsync(Context context, @NonNull StorageServiceProperties storageServiceProperties, Integer timeout, String requestId) { + return setPropertiesWithRestResponseAsync(context, storageServiceProperties, timeout, requestId) .toCompletable(); } /** * gets the properties of a storage account's Blob service, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. @@ -172,32 +178,34 @@ public Completable setPropertiesAsync(@NonNull StorageServiceProperties storageS * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the StorageServiceProperties object if successful. */ - public StorageServiceProperties getProperties(Integer timeout, String requestId) { - return getPropertiesAsync(timeout, requestId).blockingGet(); + public StorageServiceProperties getProperties(Context context, Integer timeout, String requestId) { + return getPropertiesAsync(context, timeout, requestId).blockingGet(); } /** * gets the properties of a storage account's Blob service, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getPropertiesAsync(Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getPropertiesAsync(timeout, requestId), serviceCallback); + public ServiceFuture getPropertiesAsync(Context context, Integer timeout, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getPropertiesAsync(context, timeout, requestId), serviceCallback); } /** * gets the properties of a storage account's Blob service, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getPropertiesWithRestResponseAsync(Integer timeout, String requestId) { + public Single getPropertiesWithRestResponseAsync(Context context, Integer timeout, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -206,25 +214,27 @@ public Single getPropertiesWithRestResponseAsync(I } final String restype = "service"; final String comp = "properties"; - return service.getProperties(this.client.url(), timeout, this.client.version(), requestId, restype, comp); + return service.getProperties(context, this.client.url(), timeout, this.client.version(), requestId, restype, comp); } /** * gets the properties of a storage account's Blob service, including properties for Storage Analytics and CORS (Cross-Origin Resource Sharing) rules. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe getPropertiesAsync(Integer timeout, String requestId) { - return getPropertiesWithRestResponseAsync(timeout, requestId) + public Maybe getPropertiesAsync(Context context, Integer timeout, String requestId) { + return getPropertiesWithRestResponseAsync(context, timeout, requestId) .flatMapMaybe((ServiceGetPropertiesResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * Retrieves statistics related to replication for the Blob service. It is only available on the secondary location endpoint when read-access geo-redundant replication is enabled for the storage account. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. @@ -232,32 +242,34 @@ public Maybe getPropertiesAsync(Integer timeout, Strin * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the StorageServiceStats object if successful. */ - public StorageServiceStats getStatistics(Integer timeout, String requestId) { - return getStatisticsAsync(timeout, requestId).blockingGet(); + public StorageServiceStats getStatistics(Context context, Integer timeout, String requestId) { + return getStatisticsAsync(context, timeout, requestId).blockingGet(); } /** * Retrieves statistics related to replication for the Blob service. It is only available on the secondary location endpoint when read-access geo-redundant replication is enabled for the storage account. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getStatisticsAsync(Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getStatisticsAsync(timeout, requestId), serviceCallback); + public ServiceFuture getStatisticsAsync(Context context, Integer timeout, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getStatisticsAsync(context, timeout, requestId), serviceCallback); } /** * Retrieves statistics related to replication for the Blob service. It is only available on the secondary location endpoint when read-access geo-redundant replication is enabled for the storage account. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getStatisticsWithRestResponseAsync(Integer timeout, String requestId) { + public Single getStatisticsWithRestResponseAsync(Context context, Integer timeout, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -266,25 +278,27 @@ public Single getStatisticsWithRestResponseAsync(I } final String restype = "service"; final String comp = "stats"; - return service.getStatistics(this.client.url(), timeout, this.client.version(), requestId, restype, comp); + return service.getStatistics(context, this.client.url(), timeout, this.client.version(), requestId, restype, comp); } /** * Retrieves statistics related to replication for the Blob service. It is only available on the secondary location endpoint when read-access geo-redundant replication is enabled for the storage account. * + * @param context The context to associate with this operation. * @param timeout The timeout parameter is expressed in seconds. For more information, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/setting-timeouts-for-blob-service-operations">Setting Timeouts for Blob Service Operations.</a>. * @param requestId Provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe getStatisticsAsync(Integer timeout, String requestId) { - return getStatisticsWithRestResponseAsync(timeout, requestId) + public Maybe getStatisticsAsync(Context context, Integer timeout, String requestId) { + return getStatisticsWithRestResponseAsync(context, timeout, requestId) .flatMapMaybe((ServiceGetStatisticsResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * The List Containers Segment operation returns a list of the containers under the specified account. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -296,13 +310,14 @@ public Maybe getStatisticsAsync(Integer timeout, String req * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. * @return the ListContainersSegmentResponse object if successful. */ - public ListContainersSegmentResponse listContainersSegment(String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId) { - return listContainersSegmentAsync(prefix, marker, maxresults, include, timeout, requestId).blockingGet(); + public ListContainersSegmentResponse listContainersSegment(Context context, String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId) { + return listContainersSegmentAsync(context, prefix, marker, maxresults, include, timeout, requestId).blockingGet(); } /** * The List Containers Segment operation returns a list of the containers under the specified account. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -313,13 +328,14 @@ public ListContainersSegmentResponse listContainersSegment(String prefix, String * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture listContainersSegmentAsync(String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId, ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(listContainersSegmentAsync(prefix, marker, maxresults, include, timeout, requestId), serviceCallback); + public ServiceFuture listContainersSegmentAsync(Context context, String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(listContainersSegmentAsync(context, prefix, marker, maxresults, include, timeout, requestId), serviceCallback); } /** * The List Containers Segment operation returns a list of the containers under the specified account. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -329,7 +345,7 @@ public ServiceFuture listContainersSegmentAsync(S * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single listContainersSegmentWithRestResponseAsync(String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId) { + public Single listContainersSegmentWithRestResponseAsync(Context context, String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -337,12 +353,13 @@ public Single listContainersSegmentWithRes throw new IllegalArgumentException("Parameter this.client.version() is required and cannot be null."); } final String comp = "list"; - return service.listContainersSegment(this.client.url(), prefix, marker, maxresults, include, timeout, this.client.version(), requestId, comp); + return service.listContainersSegment(context, this.client.url(), prefix, marker, maxresults, include, timeout, this.client.version(), requestId, comp); } /** * The List Containers Segment operation returns a list of the containers under the specified account. * + * @param context The context to associate with this operation. * @param prefix Filters the results to return only containers whose name begins with the specified prefix. * @param marker A string value that identifies the portion of the list of containers to be returned with the next listing operation. The operation returns the NextMarker value within the response body if the listing operation did not return all containers remaining to be listed with the current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the client. * @param maxresults Specifies the maximum number of containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the service will return fewer results than specified by maxresults, or than the default of 5000. @@ -352,38 +369,43 @@ public Single listContainersSegmentWithRes * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Maybe listContainersSegmentAsync(String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId) { - return listContainersSegmentWithRestResponseAsync(prefix, marker, maxresults, include, timeout, requestId) + public Maybe listContainersSegmentAsync(Context context, String prefix, String marker, Integer maxresults, ListContainersIncludeType include, Integer timeout, String requestId) { + return listContainersSegmentWithRestResponseAsync(context, prefix, marker, maxresults, include, timeout, requestId) .flatMapMaybe((ServiceListContainersSegmentResponse res) -> res.body() == null ? Maybe.empty() : Maybe.just(res.body())); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @throws StorageErrorException thrown if the request is rejected by server. * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent. */ - public void getAccountInfo() { - getAccountInfoAsync().blockingAwait(); + public void getAccountInfo(Context context) { + getAccountInfoAsync(context).blockingAwait(); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. * @param serviceCallback the async ServiceCallback to handle successful and failed responses. * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a ServiceFuture which will be completed with the result of the network request. */ - public ServiceFuture getAccountInfoAsync(ServiceCallback serviceCallback) { - return ServiceFuture.fromBody(getAccountInfoAsync(), serviceCallback); + public ServiceFuture getAccountInfoAsync(Context context, ServiceCallback serviceCallback) { + return ServiceFuture.fromBody(getAccountInfoAsync(context), serviceCallback); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Single getAccountInfoWithRestResponseAsync() { + public Single getAccountInfoWithRestResponseAsync(Context context) { if (this.client.url() == null) { throw new IllegalArgumentException("Parameter this.client.url() is required and cannot be null."); } @@ -392,16 +414,18 @@ public Single getAccountInfoWithRestResponseAsync } final String restype = "account"; final String comp = "properties"; - return service.getAccountInfo(this.client.url(), this.client.version(), restype, comp); + return service.getAccountInfo(context, this.client.url(), this.client.version(), restype, comp); } /** * Returns the sku name and account kind. * + * @param context The context to associate with this operation. + * @throws IllegalArgumentException thrown if parameters fail the validation. * @return a Single which performs the network request upon subscription. */ - public Completable getAccountInfoAsync() { - return getAccountInfoWithRestResponseAsync() + public Completable getAccountInfoAsync(Context context) { + return getAccountInfoWithRestResponseAsync(context) .toCompletable(); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/AccountSASPermission.java b/src/main/java/com/microsoft/azure/storage/blob/AccountSASPermission.java index df3ce3824194..9787bbe38951 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/AccountSASPermission.java +++ b/src/main/java/com/microsoft/azure/storage/blob/AccountSASPermission.java @@ -24,50 +24,147 @@ * the order of the permissions is particular and this class guarantees correctness. */ public final class AccountSASPermission { + + private boolean read; + + private boolean add; + + private boolean create; + + private boolean write; + + private boolean delete; + + private boolean list; + + private boolean update; + + private boolean processMessages; + + /** + * Initializes an {@code AccountSASPermission} object with all fields set to false. + */ + public AccountSASPermission() {} + + /** + * Permission to read resources and list queues and tables granted. + */ + public boolean read() { + return read; + } + /** * Permission to read resources and list queues and tables granted. */ - public boolean read; + public AccountSASPermission withRead(boolean read) { + this.read = read; + return this; + } /** * Permission to add messages, table entities, and append to blobs granted. */ - public boolean add; + public boolean add() { + return add; + } + + /** + * Permission to add messages, table entities, and append to blobs granted. + */ + public AccountSASPermission withAdd(boolean add) { + this.add = add; + return this; + } /** * Permission to create blobs and files granted. */ - public boolean create; + public boolean create() { + return create; + } + + /** + * Permission to create blobs and files granted. + */ + public AccountSASPermission withCreate(boolean create) { + this.create = create; + return this; + } + + /** + * Permission to write resources granted. + */ + public boolean write() { + return write; + } /** * Permission to write resources granted. */ - public boolean write; + public AccountSASPermission withWrite(boolean write) { + this.write = write; + return this; + } /** * Permission to delete resources granted. */ - public boolean delete; + public boolean delete() { + return delete; + } + + /** + * Permission to delete resources granted. + */ + public AccountSASPermission withDelete(boolean delete) { + this.delete = delete; + return this; + } /** * Permission to list blob containers, blobs, shares, directories, and files granted. */ - public boolean list; + public boolean list() { + return list; + } + + /** + * Permission to list blob containers, blobs, shares, directories, and files granted. + */ + public AccountSASPermission withList(boolean list) { + this.list = list; + return this; + } + + /** + * Permissions to update messages and table entities granted. + */ + public boolean update() { + return update; + } /** * Permissions to update messages and table entities granted. */ - public boolean update; + public AccountSASPermission withUpdate(boolean update) { + this.update = update; + return this; + } /** * Permission to get and delete messages granted. */ - public boolean processMessages; + public boolean processMessages() { + return processMessages; + } /** - * Initializes an {@code AccountSASPermssion} object with all fields set to false. + * Permission to get and delete messages granted. */ - public AccountSASPermission() {} + public AccountSASPermission withProcessMessages(boolean processMessages) { + this.processMessages = processMessages; + return this; + } /** * Converts the given permissions to a {@code String}. Using this method will guarantee the permissions are in an diff --git a/src/main/java/com/microsoft/azure/storage/blob/AccountSASResourceType.java b/src/main/java/com/microsoft/azure/storage/blob/AccountSASResourceType.java index 3b5f723140a6..4b536baa2cf6 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/AccountSASResourceType.java +++ b/src/main/java/com/microsoft/azure/storage/blob/AccountSASResourceType.java @@ -24,20 +24,57 @@ * the order of the resources is particular and this class guarantees correctness. */ public final class AccountSASResourceType { + + private boolean service; + + private boolean container; + + private boolean object; + /** * Permission to access service level APIs granted. */ - public boolean service; + public boolean service() { + return service; + } + + /** + * Permission to access service level APIs granted. + */ + public AccountSASResourceType withService(boolean service) { + this.service = service; + return this; + } + + /** + * Permission to access container level APIs (Blob Containers, Tables, Queues, File Shares) granted. + */ + public boolean container() { + return container; + } /** * Permission to access container level APIs (Blob Containers, Tables, Queues, File Shares) granted. */ - public boolean container; + public AccountSASResourceType withContainer(boolean container) { + this.container = container; + return this; + } /** * Permission to access object level APIs (Blobs, Table Entities, Queue Messages, Files) granted. */ - public boolean object; + public boolean object() { + return object; + } + + /** + * Permission to access object level APIs (Blobs, Table Entities, Queue Messages, Files) granted. + */ + public AccountSASResourceType withObject(boolean object) { + this.object = object; + return this; + } /** * Initializes an {@code AccountSASResourceType} object with all fields set to false. diff --git a/src/main/java/com/microsoft/azure/storage/blob/AccountSASService.java b/src/main/java/com/microsoft/azure/storage/blob/AccountSASService.java index 76785c0d6e4f..e53fe5d6612e 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/AccountSASService.java +++ b/src/main/java/com/microsoft/azure/storage/blob/AccountSASService.java @@ -24,25 +24,74 @@ * the order of the services is particular and this class guarantees correctness. */ public final class AccountSASService { + + private boolean blob; + + private boolean file; + + private boolean queue; + + private boolean table; + /** * Permission to access blob resources granted. */ - public boolean blob; + public boolean blob() { + return blob; + } + + /** + * Permission to access blob resources granted. + */ + public AccountSASService withBlob(boolean blob) { + this.blob = blob; + return this; + } /** * Permission to access file resources granted. */ - public boolean file; + public boolean file() { + return file; + } + + /** + * Permission to access file resources granted. + */ + public AccountSASService withFile(boolean file) { + this.file = file; + return this; + } + + /** + * Permission to access queue resources granted. + */ + public boolean queue() { + return queue; + } /** * Permission to access queue resources granted. */ - public boolean queue; + public AccountSASService withQueue(boolean queue) { + this.queue = queue; + return this; + } /** * Permission to access table resources granted. */ - public boolean table; + public boolean table() { + return table; + } + + /** + * Permission to access table resources granted. + */ + public AccountSASService withTable(boolean table) { + this.table = table; + return this; + } /** * Initializes an {@code AccountSASService} object with all fields set to false. diff --git a/src/main/java/com/microsoft/azure/storage/blob/AccountSASSignatureValues.java b/src/main/java/com/microsoft/azure/storage/blob/AccountSASSignatureValues.java index 97306c99f4a2..c35a549de8a6 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/AccountSASSignatureValues.java +++ b/src/main/java/com/microsoft/azure/storage/blob/AccountSASSignatureValues.java @@ -40,48 +40,147 @@ */ public final class AccountSASSignatureValues { + private String version = Constants.HeaderConstants.TARGET_STORAGE_VERSION; + + private SASProtocol protocol; + + private OffsetDateTime startTime; + + private OffsetDateTime expiryTime; + + private String permissions; + + private IPRange ipRange; + + private String services; + + private String resourceTypes; + /** * If null or empty, this defaults to the service version targeted by this version of the library. */ - public String version = Constants.HeaderConstants.TARGET_STORAGE_VERSION; + public String version() { + return version; + } + + /** + * If null or empty, this defaults to the service version targeted by this version of the library. + */ + public AccountSASSignatureValues withVersion(String version) { + this.version = version; + return this; + } + + /** + * {@link SASProtocol} + */ + public SASProtocol protocol() { + return protocol; + } /** * {@link SASProtocol} */ - public SASProtocol protocol; + public AccountSASSignatureValues withProtocol(SASProtocol protocol) { + this.protocol = protocol; + return this; + } /** * When the SAS will take effect. */ - public OffsetDateTime startTime; + public OffsetDateTime startTime() { + return startTime; + } + + /** + * When the SAS will take effect. + */ + public AccountSASSignatureValues withStartTime(OffsetDateTime startTime) { + this.startTime = startTime; + return this; + } /** * The time after which the SAS will no longer work. */ - public OffsetDateTime expiryTime; + public OffsetDateTime expiryTime() { + return expiryTime; + } + + /** + * The time after which the SAS will no longer work. + */ + public AccountSASSignatureValues withExpiryTime(OffsetDateTime expiryTime) { + this.expiryTime = expiryTime; + return this; + } /** * Specifies which operations the SAS user may perform. Please refer to {@link AccountSASPermission} for help * constructing the permissions string. */ - public String permissions; + public String permissions() { + return permissions; + } + + /** + * Specifies which operations the SAS user may perform. Please refer to {@link AccountSASPermission} for help + * constructing the permissions string. + */ + public AccountSASSignatureValues withPermissions(String permissions) { + this.permissions = permissions; + return this; + } /** * {@link IPRange} */ - public IPRange ipRange; + public IPRange ipRange() { + return ipRange; + } + + /** + * {@link IPRange} + */ + public AccountSASSignatureValues withIpRange(IPRange ipRange) { + this.ipRange = ipRange; + return this; + } /** * The values that indicate the services accessible with this SAS. Please refer to {@link AccountSASService} to * construct this value. */ - public String services; + public String services() { + return services; + } + + /** + * The values that indicate the services accessible with this SAS. Please refer to {@link AccountSASService} to + * construct this value. + */ + public AccountSASSignatureValues withServices(String services) { + this.services = services; + return this; + } /** * The values that indicate the resource types accessible with this SAS. Please refer * to {@link AccountSASResourceType} to construct this value. */ - public String resourceTypes; + public String resourceTypes() { + return resourceTypes; + } + + /** + * The values that indicate the resource types accessible with this SAS. Please refer + * to {@link AccountSASResourceType} to construct this value. + */ + public AccountSASSignatureValues withResourceTypes(String resourceTypes) { + this.resourceTypes = resourceTypes; + return this; + } /** * Initializes an {@code AccountSASSignatureValues} object with the version number set to the default and all diff --git a/src/main/java/com/microsoft/azure/storage/blob/AppendBlobAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/AppendBlobAccessConditions.java index c9df06662fcb..e2ea2156898a 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/AppendBlobAccessConditions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/AppendBlobAccessConditions.java @@ -14,10 +14,13 @@ */ package com.microsoft.azure.storage.blob; +import com.microsoft.azure.storage.blob.models.AppendPositionAccessConditions; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; + /** * This class contains values that restrict the successful completion of AppendBlock operations to certain conditions. - * An instance of this class is set as a member of {@link BlobAccessConditions} when needed. Any field may be set to - * null if no access conditions are desired. + * Any field may be set to null if no access conditions are desired. * * Please refer to the request header section * here for more conceptual @@ -29,44 +32,63 @@ public final class AppendBlobAccessConditions { * An object representing no access conditions. */ public static final AppendBlobAccessConditions NONE = - new AppendBlobAccessConditions(null, null); + new AppendBlobAccessConditions(); + + private AppendPositionAccessConditions appendPositionAccessConditions; - private final Long ifAppendPositionEquals; + private ModifiedAccessConditions modifiedAccessConditions; - private final Long ifMaxSizeLessThanOrEqual; + private LeaseAccessConditions leaseAccessConditions; + + /** + * {@link AppendPositionAccessConditions} + */ + public AppendPositionAccessConditions appendPositionAccessConditions() { + return appendPositionAccessConditions; + } /** - * Creates a {@code AppendBlobAccessConditions} object. - * - * @param ifAppendPositionEquals - * Ensures that the AppendBlock operation succeeds only if the append position is equal to a value. - * @param ifMaxSizeLessThanOrEqual - * Ensures that the AppendBlock operation succeeds only if the append blob's size is less than or - * equal to a value. + * {@link AppendPositionAccessConditions} */ - public AppendBlobAccessConditions(Long ifAppendPositionEquals, Long ifMaxSizeLessThanOrEqual) { - if ((ifAppendPositionEquals != null && ifAppendPositionEquals < -1) || - (ifMaxSizeLessThanOrEqual != null && ifMaxSizeLessThanOrEqual < -1)) { - throw new IllegalArgumentException("Append blob access conditions can't be less than -1."); - } - this.ifAppendPositionEquals = ifAppendPositionEquals; - this.ifMaxSizeLessThanOrEqual = ifMaxSizeLessThanOrEqual; + public AppendBlobAccessConditions withAppendPositionAccessConditions( + AppendPositionAccessConditions appendPositionAccessConditions) { + this.appendPositionAccessConditions = appendPositionAccessConditions; + return this; } /** - * @return - * Ensures that the AppendBlock operation succeeds only if the append position is equal to the value. + * {@link ModifiedAccessConditions} */ - public Long getIfAppendPositionEquals() { - return ifAppendPositionEquals; + public ModifiedAccessConditions modifiedAccessConditions() { + return modifiedAccessConditions; } /** - * @return - * Ensures that the AppendBlock operation succeeds only if the append blob's size is less than or equal to the - * value. + * {@link ModifiedAccessConditions} */ - public Long getIfMaxSizeLessThanOrEqual() { - return ifMaxSizeLessThanOrEqual; + public AppendBlobAccessConditions withModifiedAccessConditions(ModifiedAccessConditions modifiedAccessConditions) { + this.modifiedAccessConditions = modifiedAccessConditions; + return this; } + + /** + * {@link LeaseAccessConditions} + */ + public LeaseAccessConditions leaseAccessConditions() { + return leaseAccessConditions; + } + + /** + * {@link LeaseAccessConditions} + */ + public AppendBlobAccessConditions withLeaseAccessConditions(LeaseAccessConditions leaseAccessConditions) { + this.leaseAccessConditions = leaseAccessConditions; + return this; + } + + public AppendBlobAccessConditions() { + appendPositionAccessConditions = new AppendPositionAccessConditions(); + modifiedAccessConditions = new ModifiedAccessConditions(); + leaseAccessConditions = new LeaseAccessConditions(); + } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/AppendBlobURL.java b/src/main/java/com/microsoft/azure/storage/blob/AppendBlobURL.java index 175bb20f7168..b7039938ca3d 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/AppendBlobURL.java +++ b/src/main/java/com/microsoft/azure/storage/blob/AppendBlobURL.java @@ -15,6 +15,7 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.*; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.http.HttpPipeline; import io.reactivex.Flowable; import io.reactivex.Single; @@ -87,7 +88,7 @@ public AppendBlobURL withPipeline(HttpPipeline pipeline) { */ public AppendBlobURL withSnapshot(String snapshot) throws MalformedURLException, UnknownHostException { BlobURLParts blobURLParts = URLParser.parse(new URL(this.storageClient.url())); - blobURLParts.snapshot = snapshot; + blobURLParts.withSnapshot(snapshot); return new AppendBlobURL(blobURLParts.toURL(), super.storageClient.httpPipeline()); } @@ -106,64 +107,66 @@ public AppendBlobURL withSnapshot(String snapshot) throws MalformedURLException, * {@link Metadata} * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single create( - BlobHTTPHeaders headers, Metadata metadata, BlobAccessConditions accessConditions) { - headers = headers == null ? BlobHTTPHeaders.NONE : headers; + public Single create(BlobHTTPHeaders headers, Metadata metadata, + BlobAccessConditions accessConditions, Context context) { metadata = metadata == null ? Metadata.NONE : metadata; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; - return addErrorWrappingToSingle(this.storageClient.generatedAppendBlobs().createWithRestResponseAsync( - 0, null, - headers.getContentType(), - headers.getContentEncoding(), - headers.getContentLanguage(), - headers.getContentMD5(), - headers.getCacheControl(), - metadata, - accessConditions.getLeaseAccessConditions().getLeaseId(), - headers.getContentDisposition(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + return addErrorWrappingToSingle(this.storageClient.generatedAppendBlobs().createWithRestResponseAsync(context, + 0, null, metadata, null, headers, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** * Commits a new block of data to the end of the existing append blob. For more information, see the * Azure Docs. * + * Note that the data passed must be replayable if retries are enabled (the default). In other words, the + * {@code Flowable} must produce the same data each time it is subscribed to. + * * @apiNote * ## Sample Code \n * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=append_blob "Sample code for AppendBlobURL.appendBlock")] \n * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * * @param data - * The data to write to the blob. + * The data to write to the blob. Note that this {@code Flowable} must be replayable if retries are enabled + * (the default). In other words, the Flowable must produce the same data each time it is subscribed to. * @param length * The exact length of the data. It is important that this value match precisely the length of the data * emitted by the {@code Flowable}. - * @param accessConditions - * {@link BlobAccessConditions} + * @param appendBlobAccessConditions + * {@link AppendBlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single appendBlock( - Flowable data, long length, BlobAccessConditions accessConditions) { - accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + public Single appendBlock(Flowable data, long length, + AppendBlobAccessConditions appendBlobAccessConditions, Context context) { + appendBlobAccessConditions = appendBlobAccessConditions == null ? AppendBlobAccessConditions.NONE : + appendBlobAccessConditions; + appendBlobAccessConditions = appendBlobAccessConditions == null + ? AppendBlobAccessConditions.NONE : appendBlobAccessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedAppendBlobs().appendBlockWithRestResponseAsync( - data, length, null, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getAppendBlobAccessConditions().getIfMaxSizeLessThanOrEqual(), - accessConditions.getAppendBlobAccessConditions().getIfAppendPositionEquals(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context, data, length, null, null, null, appendBlobAccessConditions.leaseAccessConditions(), + appendBlobAccessConditions.appendPositionAccessConditions(), + appendBlobAccessConditions.modifiedAccessConditions())); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlobAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/BlobAccessConditions.java index abaaf28ae3fd..19b86ccd41bb 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/BlobAccessConditions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/BlobAccessConditions.java @@ -14,6 +14,9 @@ */ package com.microsoft.azure.storage.blob; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; + /** * This class contains values which will restrict the successful operation of a variety of requests to the conditions * present. These conditions are entirely optional. The entire object or any of its properties may be set to null when @@ -22,82 +25,45 @@ */ public final class BlobAccessConditions { - /** - * An object representing no access conditions. - */ public static final BlobAccessConditions NONE = - new BlobAccessConditions(null, null, null, - null); - - // Optional standard HTTP access conditions which are optionally set - private final HTTPAccessConditions httpAccessConditions; + new BlobAccessConditions(); - // Optional access conditions for a lease on a container or blob - private final LeaseAccessConditions leaseAccessConditions; + private ModifiedAccessConditions modifiedAccessConditions; - // Optional access conditions which are specific to append blobs - private final AppendBlobAccessConditions appendBlobAccessConditions; - - // Optional access conditions which are specific to page blobs - private final PageBlobAccessConditions pageBlobAccessConditions; + private LeaseAccessConditions leaseAccessConditions; /** - * Access conditions which are specific to blobs. - * - * @param httpAccessConditions - * {@link HTTPAccessConditions} - * @param leaseAccessConditions - * {@link LeaseAccessConditions} - * @param appendBlobAccessConditions - * {@link AppendBlobAccessConditions} - * @param pageBlobAccessConditions - * {@link PageBlobAccessConditions} + * {@link ModifiedAccessConditions} */ - public BlobAccessConditions( - HTTPAccessConditions httpAccessConditions, - LeaseAccessConditions leaseAccessConditions, - AppendBlobAccessConditions appendBlobAccessConditions, - PageBlobAccessConditions pageBlobAccessConditions) { - this.httpAccessConditions = httpAccessConditions == null ? - HTTPAccessConditions.NONE : httpAccessConditions; - this.leaseAccessConditions = leaseAccessConditions == null ? - LeaseAccessConditions.NONE : leaseAccessConditions; - this.appendBlobAccessConditions = appendBlobAccessConditions == null ? - AppendBlobAccessConditions.NONE : appendBlobAccessConditions; - this.pageBlobAccessConditions = pageBlobAccessConditions == null ? - PageBlobAccessConditions.NONE : pageBlobAccessConditions; + public ModifiedAccessConditions modifiedAccessConditions() { + return modifiedAccessConditions; } /** - * @return - * The HttpAccessConditions. + * {@link ModifiedAccessConditions} */ - HTTPAccessConditions getHttpAccessConditions() { - return httpAccessConditions; + public BlobAccessConditions withModifiedAccessConditions(ModifiedAccessConditions modifiedAccessConditions) { + this.modifiedAccessConditions = modifiedAccessConditions; + return this; } /** - * @return - * The LeaseAccessConditions. + * {@link LeaseAccessConditions} */ - LeaseAccessConditions getLeaseAccessConditions() { + public LeaseAccessConditions leaseAccessConditions() { return leaseAccessConditions; } /** - * @return - * The AppendBlobAccessConditions. + * {@link LeaseAccessConditions} */ - AppendBlobAccessConditions getAppendBlobAccessConditions() { - return appendBlobAccessConditions; + public BlobAccessConditions withLeaseAccessConditions(LeaseAccessConditions leaseAccessConditions) { + this.leaseAccessConditions = leaseAccessConditions; + return this; } - /** - * @return - * The PageBlobAccessConditions. - */ - PageBlobAccessConditions getPageBlobAccessConditions() { - return pageBlobAccessConditions; + public BlobAccessConditions() { + modifiedAccessConditions = new ModifiedAccessConditions(); + leaseAccessConditions = new LeaseAccessConditions(); } - } diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlobHTTPHeaders.java b/src/main/java/com/microsoft/azure/storage/blob/BlobHTTPHeaders.java deleted file mode 100644 index b46fba0743ec..000000000000 --- a/src/main/java/com/microsoft/azure/storage/blob/BlobHTTPHeaders.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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; - -/** - * Most often used when creating a blob or setting its properties, this class contains fields for typical HTTP - * properties, which, if specified, will be attached to the target blob. Null may be passed to any API which takes this - * type to indicate that no properties should be set. - */ -public final class BlobHTTPHeaders { - - /** - * An object representing no blob properties. - */ - public static final BlobHTTPHeaders NONE = new BlobHTTPHeaders(null, null, - null,null, null, null); - - private final String cacheControl; - - private final String contentDisposition; - - private final String contentEncoding; - - private final String contentLanguage; - - private final byte[] contentMD5; - - private final String contentType; - - /** - * A {@link BlobHTTPHeaders} object. - * - * @param cacheControl - * The cache-control value stored for the blob. - * @param contentDisposition - * The content-disposition value stored for the blob. - * @param contentEncoding - * The content-encoding value stored for the blob. - * @param contentLanguage - * The content-language value stored for the blob. - * @param contentMD5 - * The content-MD5 value stored for the blob. - * @param contentType - * The content-type value stored for the blob. - */ - public BlobHTTPHeaders(String cacheControl, String contentDisposition, String contentEncoding, - String contentLanguage, byte[] contentMD5, String contentType) { - this.cacheControl = cacheControl; - this.contentDisposition = contentDisposition; - this.contentEncoding = contentEncoding; - this.contentLanguage = contentLanguage; - this.contentMD5 = contentMD5; - this.contentType = contentType; - } - - /** - * @return - * The cache-control value stored for the blob. - */ - public String getCacheControl() { - return cacheControl; - } - - /** - * @return - * The content-disposition value stored for the blob. - */ - public String getContentDisposition() { - return contentDisposition; - } - - /** - * @return - * The content-encoding value stored for the blob. - */ - public String getContentEncoding() { - return contentEncoding; - } - - /** - * @return - * The content-language value stored for the blob. - */ - public String getContentLanguage() { - return contentLanguage; - } - - /** - * @return - * The content-MD5 value stored for the blob. - */ - public byte[] getContentMD5() { - return contentMD5; - } - - /** - * @return - * The content-type value stored for the blob. - */ - public String getContentType() { - return contentType; - } - -} diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlobListingDetails.java b/src/main/java/com/microsoft/azure/storage/blob/BlobListingDetails.java index 06a3c7205fde..6fbde2573e36 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/BlobListingDetails.java +++ b/src/main/java/com/microsoft/azure/storage/blob/BlobListingDetails.java @@ -29,87 +29,103 @@ public final class BlobListingDetails { /** * An object representing no listing details. */ - public static final BlobListingDetails NONE = new BlobListingDetails(false, false, false, - false, false); + public static final BlobListingDetails NONE = new BlobListingDetails(); - private final boolean copy; + private boolean copy; - private final boolean metadata; + private boolean metadata; - private final boolean snapshots; + private boolean snapshots; - private final boolean uncommittedBlobs; + private boolean uncommittedBlobs; - private final boolean deletedBlobs; + private boolean deletedBlobs; + + public BlobListingDetails() { + } + + /** + * Whether blob metadata related to any current or previous Copy Blob operation should be included in the + * response. + */ + public boolean copy() { + return copy; + } /** - * A {@link BlobListingDetails} object. - * - * @param copy - * Whether blob metadata related to any current or previous Copy Blob operation should be included in the - * response. - * @param metadata - * Whether blob metadata should be returned. - * @param snapshots - * Whether snapshots should be returned. Snapshots are listed from oldest to newest. - * @param uncommittedBlobs - * Whether blobs for which blocks have been uploaded, but which have not been committed using Put Block List, - * should be included in the response. - * @param deletedBlobs - * Whether blobs which have been soft deleted should be returned. + * Whether blob metadata related to any current or previous Copy Blob operation should be included in the + * response. */ - public BlobListingDetails(boolean copy, boolean metadata, boolean snapshots, boolean uncommittedBlobs, - boolean deletedBlobs) { + public BlobListingDetails withCopy(boolean copy) { this.copy = copy; + return this; + } + + /** + * Whether blob metadata should be returned. + */ + public boolean metadata() { + return metadata; + } + + /** + * Whether blob metadata should be returned. + */ + public BlobListingDetails withMetadata(boolean metadata) { this.metadata = metadata; - this.snapshots = snapshots; - this.uncommittedBlobs = uncommittedBlobs; - this.deletedBlobs = deletedBlobs; + return this; + } + + /** + * Whether snapshots should be returned. Snapshots are listed from oldest to newest. + */ + public boolean snapshots() { + return snapshots; } /** - * @return - * Whether blob copies should be returned. + * Whether snapshots should be returned. Snapshots are listed from oldest to newest. */ - public boolean getCopy() { - return this.copy; + public BlobListingDetails withSnapshots(boolean snapshots) { + this.snapshots = snapshots; + return this; } /** - * @return - * Whether metadata should be returned. + * Whether blobs for which blocks have been uploaded, but which have not been committed using Put Block List, + * should be included in the response. */ - public boolean getMetadata() { - return this.metadata; + public boolean uncommittedBlobs() { + return uncommittedBlobs; } /** - * @return - * Whether snapshots should be returned. + * Whether blobs for which blocks have been uploaded, but which have not been committed using Put Block List, + * should be included in the response. */ - public boolean getSnapshots() { - return this.snapshots; + public BlobListingDetails withUncommittedBlobs(boolean uncommittedBlobs) { + this.uncommittedBlobs = uncommittedBlobs; + return this; } /** - * @return - * Whether uncommitted blobs should be returned. + * Whether blobs which have been soft deleted should be returned. */ - public boolean getUncommittedBlobs() { - return this.uncommittedBlobs; + public boolean deletedBlobs() { + return deletedBlobs; } /** - * @return - * Whether soft-deleted blobs should be returned. + * Whether blobs which have been soft deleted should be returned. */ - public boolean getDeletedBlobs() { - return this.deletedBlobs; + public BlobListingDetails withDeletedBlobs(boolean deletedBlobs) { + this.deletedBlobs = deletedBlobs; + return this; } /* - This is used internally to convert the details structure into a list to pass to the protocol layer. The customer - should never have need for this. + This is used internally to convert the details structure into a list to pass to the protocol layer. The customer + should never have need for this. */ ArrayList toList() { ArrayList details = new ArrayList(); diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlobRange.java b/src/main/java/com/microsoft/azure/storage/blob/BlobRange.java index 878819b257df..d8d348b209f2 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/BlobRange.java +++ b/src/main/java/com/microsoft/azure/storage/blob/BlobRange.java @@ -26,59 +26,59 @@ public final class BlobRange { /** * An object which reflects the service's default range, which is the whole blob. */ - public static final BlobRange DEFAULT = new BlobRange(0, null); + public static final BlobRange DEFAULT = new BlobRange(); - private final long offset; + private long offset; - private final Long count; + private Long count; + + public BlobRange() { + } /** - * A {@code BlobRange} object. - * - * @param offset - * The start of the range. Must be greater than or equal to 0. - * @param count - * How many bytes to include in the range. Must be greater than or equal to 0 if specified. If specified, - * offset must also be specified. + * The start of the range. Must be greater than or equal to 0. */ - public BlobRange(long offset, Long count) { + public long offset() { + return offset; + } + + /** + * The start of the range. Must be greater than or equal to 0. + */ + public BlobRange withOffset(long offset) { if (offset < 0) { throw new IllegalArgumentException("BlobRange offset must be greater than or equal to 0."); } - if (count != null && count < 0) { - throw new IllegalArgumentException( - "BlobRange count must be greater than or equal to 0 if specified. Cannot be specified without an " + - "offset."); - } this.offset = offset; - this.count = count; + return this; } /** - * @return - * Indicates the start of the range. + * How many bytes to include in the range. Must be greater than or equal to 0 if specified. */ - public long getOffset() { - return offset; + public Long count() { + return count; } /** - * @return - * Indicates how many bytes to include in the range. + * How many bytes to include in the range. Must be greater than or equal to 0 if specified. */ - public Long getCount() { - return count; + public BlobRange withCount(Long count) { + if (count != null && count < 0) { + throw new IllegalArgumentException( + "BlobRange count must be greater than or equal to 0 if specified."); + } + this.count = count; + return this; } - /** * @return * A {@code String} compliant with the format of the Azure Storage x-ms-range and Range headers. */ @Override public String toString() { - - if (count != null) { + if (this.count != null) { long rangeEnd = this.offset + this.count - 1; return String.format( Locale.ROOT, Constants.HeaderConstants.RANGE_HEADER_FORMAT, this.offset, rangeEnd); diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlobSASPermission.java b/src/main/java/com/microsoft/azure/storage/blob/BlobSASPermission.java index f04587f4cadc..2cc42a033f2a 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/BlobSASPermission.java +++ b/src/main/java/com/microsoft/azure/storage/blob/BlobSASPermission.java @@ -24,30 +24,91 @@ * the order of the permissions is particular and this class guarantees correctness. */ public final class BlobSASPermission { + + private boolean read; + + private boolean add; + + private boolean create; + + private boolean write; + + private boolean delete; + + /** + * Specifies Read access granted. + */ + public boolean read() { + return read; + } + /** * Specifies Read access granted. */ - public boolean read; + public BlobSASPermission withRead(boolean read) { + this.read = read; + return this; + } /** * Specifies Add access granted. */ - public boolean add; + public boolean add() { + return add; + } + + /** + * Specifies Add access granted. + */ + public BlobSASPermission withAdd(boolean add) { + this.add = add; + return this; + } + + /** + * Specifies Create access granted. + */ + public boolean create() { + return create; + } /** * Specifies Create access granted. */ - public boolean create; + public BlobSASPermission withCreate(boolean create) { + this.create = create; + return this; + } + + /** + * Specifies Write access granted. + */ + public boolean write() { + return write; + } /** * Specifies Write access granted. */ - public boolean write; + public BlobSASPermission withWrite(boolean write) { + this.write = write; + return this; + } /** * Specifies Delete access granted. */ - public boolean delete; + public boolean delete() { + return delete; + } + + /** + * Specifies Delete access granted. + */ + public BlobSASPermission withDelete(boolean delete) { + this.delete = delete; + return this; + } /** * Initializes a {@code BlobSASPermission} object with all fields set to false. diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlobURL.java b/src/main/java/com/microsoft/azure/storage/blob/BlobURL.java index fe9d7d0c00a2..e8a5e36234bb 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/BlobURL.java +++ b/src/main/java/com/microsoft/azure/storage/blob/BlobURL.java @@ -15,35 +15,34 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.*; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.http.HttpPipeline; import io.reactivex.Single; -import io.reactivex.SingleSource; -import io.reactivex.functions.Function; import java.net.MalformedURLException; import java.net.URL; import java.net.UnknownHostException; -import static com.microsoft.azure.storage.blob.Utility.*; +import static com.microsoft.azure.storage.blob.Utility.addErrorWrappingToSingle; /** * Represents a URL to a blob of any type: block, append, or page. It may be obtained by direct construction or via the * create method on a {@link ContainerURL} object. This class does not hold any state about a particular blob but is - * instead a convenient way of sending off appropriate requests to the resource on the service. Please refer to the - * Azure Docs - * for more information. + * instead a convenient way of sending off appropriate requests to the resource on the service. Please refer to the Azure + * Docs for more information. */ public class BlobURL extends StorageURL { /** - * Creates a {@code BlobURL} object pointing to the account specified by the URL and using the provided - * pipeline to make HTTP requests. + * Creates a {@code BlobURL} object pointing to the account specified by the URL and using the provided pipeline to + * make HTTP requests. * * @param url - * A {@code URL} to an Azure Storage blob. + * A {@code URL} to an Azure Storage blob. * @param pipeline - * A {@code HttpPipeline} which configures the behavior of HTTP exchanges. Please refer to the createPipeline - * method on {@link StorageURL} for more information. + * A {@code HttpPipeline} which configures the behavior of HTTP exchanges. Please refer to the + * createPipeline method on {@link StorageURL} for more information. */ public BlobURL(URL url, HttpPipeline pipeline) { super(url, pipeline); @@ -53,9 +52,8 @@ public BlobURL(URL url, HttpPipeline pipeline) { * Creates a new {@link BlobURL} with the given pipeline. * * @param pipeline - * An {@link HttpPipeline} object to set. - * @return - * A {@link BlobURL} object with the given pipeline. + * An {@link HttpPipeline} object to set. + * @return A {@link BlobURL} object with the given pipeline. */ public BlobURL withPipeline(HttpPipeline pipeline) { try { @@ -70,17 +68,16 @@ public BlobURL withPipeline(HttpPipeline pipeline) { * Creates a new {@link BlobURL} with the given snapshot. * * @param snapshot - * A {@code String} to set. + * A {@code String} to set. + * @return A {@link BlobURL} object with the given pipeline. * @throws MalformedURLException - * Appending the specified snapshot produced an invalid URL. + * Appending the specified snapshot produced an invalid URL. * @throws UnknownHostException - * If the url contains an improperly formatted ipaddress or unknown host address. - * @return - * A {@link BlobURL} object with the given pipeline. + * If the url contains an improperly formatted ipaddress or unknown host address. */ public BlobURL withSnapshot(String snapshot) throws MalformedURLException, UnknownHostException { BlobURLParts blobURLParts = URLParser.parse(new URL(this.storageClient.url())); - blobURLParts.snapshot = snapshot; + blobURLParts.withSnapshot(snapshot); return new BlobURL(blobURLParts.toURL(), super.storageClient.httpPipeline()); } @@ -88,8 +85,7 @@ public BlobURL withSnapshot(String snapshot) throws MalformedURLException, Unkno * Converts this BlobURL to a {@link BlockBlobURL} object. Note that this does not change the actual type of the * blob if it has already been created. * - * @return - * A {@link BlockBlobURL} object. + * @return A {@link BlockBlobURL} object. */ public BlockBlobURL toBlockBlobURL() { try { @@ -104,8 +100,7 @@ public BlockBlobURL toBlockBlobURL() { * Converts this BlobURL to an {@link AppendBlobURL} object. Note that this does not change the actual type of the * blob if it has already been created. * - * @return - * An {@link AppendBlobURL} object. + * @return An {@link AppendBlobURL} object. */ public AppendBlobURL toAppendBlobURL() { try { @@ -120,8 +115,7 @@ public AppendBlobURL toAppendBlobURL() { * Converts this BlobURL to a {@link PageBlobURL} object. Note that this does not change the actual type of the blob * if it has already been created. * - * @return - * A {@link PageBlobURL} object. + * @return A {@link PageBlobURL} object. */ public PageBlobURL toPageBlobURL() { try { @@ -133,416 +127,425 @@ public PageBlobURL toPageBlobURL() { } /** - * Copies the data at the source URL to a blob. For more information, see the - * Azure Docs - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=start_copy "Sample code for BlobURL.startCopyFromURL")] \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=start_copy_helper "Helper for start_copy sample.")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Copies the data at the source URL to a blob. For more information, see the Azure Docs * * @param sourceURL - * The source URL to copy from. URLs outside of Azure may only be copied to block blobs. + * The source URL to copy from. URLs outside of Azure may only be copied to block blobs. * @param metadata * {@link Metadata} - * @param sourceHttpAccessConditions - * {@link HTTPAccessConditions} against the source. + * @param sourceModifiedAccessConditions + * {@link ModifiedAccessConditions} against the source. * @param destAccessConditions * {@link BlobAccessConditions} against the destination. - * @return - * Emits the successful response. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=start_copy + * "Sample code for BlobURL.startCopyFromURL")] \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=start_copy_helper + * "Helper for start_copy sample.")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single startCopyFromURL( - URL sourceURL, Metadata metadata, HTTPAccessConditions sourceHttpAccessConditions, - BlobAccessConditions destAccessConditions) { + public Single startCopyFromURL(URL sourceURL, Metadata metadata, + ModifiedAccessConditions sourceModifiedAccessConditions, BlobAccessConditions destAccessConditions, + Context context) { metadata = metadata == null ? Metadata.NONE : metadata; - sourceHttpAccessConditions = sourceHttpAccessConditions == null ? - HTTPAccessConditions.NONE : sourceHttpAccessConditions; + sourceModifiedAccessConditions = sourceModifiedAccessConditions == null ? + new ModifiedAccessConditions() : sourceModifiedAccessConditions; destAccessConditions = destAccessConditions == null ? BlobAccessConditions.NONE : destAccessConditions; + context = context == null ? Context.NONE : context; + + // We want to hide the SourceAccessConditions type from the user for consistency's sake, so we convert here. + SourceModifiedAccessConditions sourceConditions = new SourceModifiedAccessConditions() + .withSourceIfModifiedSince(sourceModifiedAccessConditions.ifModifiedSince()) + .withSourceIfUnmodifiedSince(sourceModifiedAccessConditions.ifUnmodifiedSince()) + .withSourceIfMatch(sourceModifiedAccessConditions.ifMatch()) + .withSourceIfNoneMatch(sourceModifiedAccessConditions.ifNoneMatch()); return addErrorWrappingToSingle(this.storageClient.generatedBlobs().startCopyFromURLWithRestResponseAsync( - sourceURL, null, metadata, - sourceHttpAccessConditions.getIfModifiedSince(), - sourceHttpAccessConditions.getIfUnmodifiedSince(), - sourceHttpAccessConditions.getIfMatch().toString(), - sourceHttpAccessConditions.getIfNoneMatch().toString(), - destAccessConditions.getHttpAccessConditions().getIfModifiedSince(), - destAccessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - destAccessConditions.getHttpAccessConditions().getIfMatch().toString(), - destAccessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - destAccessConditions.getLeaseAccessConditions().getLeaseId(), - null)); + context, sourceURL, null, metadata, null, sourceConditions, + destAccessConditions.modifiedAccessConditions(), destAccessConditions.leaseAccessConditions())); } /** * Stops a pending copy that was previously started and leaves a destination blob with 0 length and metadata. For - * more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=abort_copy "Sample code for BlobURL.abortCopyFromURL")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * more information, see the Azure + * Docs. * * @param copyId - * The id of the copy operation to abort. Returned as the {@code copyId} field on the - * {@link BlobStartCopyFromURLHeaders} object. + * The id of the copy operation to abort. Returned as the {@code copyId} field on the {@link + * BlobStartCopyFromURLHeaders} object. * @param leaseAccessConditions * {@link LeaseAccessConditions} - * @return - * Emits the successful response. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=abort_copy + * "Sample code for BlobURL.abortCopyFromURL")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single abortCopyFromURL( - String copyId, LeaseAccessConditions leaseAccessConditions) { - leaseAccessConditions = leaseAccessConditions == null ? LeaseAccessConditions.NONE : leaseAccessConditions; + public Single abortCopyFromURL(String copyId, + LeaseAccessConditions leaseAccessConditions, Context context) { + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlobs().abortCopyFromURLWithRestResponseAsync( - copyId, null, leaseAccessConditions.getLeaseId(), null)); + context, copyId, null, null, leaseAccessConditions)); } /** * Reads a range of bytes from a blob. The response also includes the blob's properties and metadata. For more - * information, see the - * Azure Docs. - * - * Please consider using the {@link RetryReader} in conjunction with this method to achieve more reliable downloads - * that are resilient to transient network failures. A convenient way to do this is to simply pass non-null options - * to {@link DownloadResponse#body(RetryReaderOptions)}, and a RetryReader will be applied to the body - * automatically. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=upload_download "Sample code for BlobURL.download")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * information, see the Azure Docs. + *

+ * Note that the response body has reliable download functionality built in, meaning that a failed download stream + * will be automatically retried. This behavior may be configured with {@link ReliableDownloadOptions}. * * @param range - * {@link BlobRange} + * {@link BlobRange} * @param accessConditions - * {@link BlobAccessConditions} + * {@link BlobAccessConditions} * @param rangeGetContentMD5 - * Whether the contentMD5 for the specified blob range should be returned. - * @return - * Emits the successful response. + * Whether the contentMD5 for the specified blob range should be returned. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=upload_download + * "Sample code for BlobURL.download")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single download( - BlobRange range, BlobAccessConditions accessConditions, boolean rangeGetContentMD5) { - + public Single download(BlobRange range, BlobAccessConditions accessConditions, + boolean rangeGetContentMD5, Context context) { Boolean getMD5 = rangeGetContentMD5 ? rangeGetContentMD5 : null; range = range == null ? BlobRange.DEFAULT : range; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; - RetryReader.HTTPGetterInfo info = new RetryReader.HTTPGetterInfo(); - info.offset = range.getOffset(); - info.count = range.getCount(); - info.eTag = accessConditions.getHttpAccessConditions().getIfMatch(); + HTTPGetterInfo info = new HTTPGetterInfo() + .withCount(range.offset()) + .withCount(range.count()) + .withETag(accessConditions.modifiedAccessConditions().ifMatch()); return addErrorWrappingToSingle(this.storageClient.generatedBlobs().downloadWithRestResponseAsync( - null, null, range.toString(), - accessConditions.getLeaseAccessConditions().getLeaseId(), - getMD5, - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)) - .map(response -> - new DownloadResponse(response.request(), this, info, response.statusCode(), - response.headers(), response.rawHeaders(), response.body())); - + context, null, null, range.toString(), getMD5, null, + accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())) + // Convert the autorest response to a DownloadResponse, which enable reliable download. + .map(response -> { + // If there wasn't an etag originally specified, lock on the one returned. + info.withETag(response.headers().eTag()); + return new DownloadResponse(response, info, + // In the event of a stream failure, make a new request to pick up where we left off. + newInfo -> + this.download(new BlobRange().withOffset(newInfo.offset()) + .withCount(newInfo.count()), + new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfMatch(info.eTag())), false, + context == null ? Context.NONE : context)); + }); } /** * Deletes the specified blob or snapshot. Note that deleting a blob also deletes all its snapshots. For more - * information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_delete "Sample code for BlobURL.delete")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * information, see the Azure Docs. * * @param deleteBlobSnapshotOptions - * Specifies the behavior for deleting the snapshots on this blob. {@code Include} will delete the base blob - * and all snapshots. {@code Only} will delete only the snapshots. If a snapshot is being deleted, you must - * pass null. + * Specifies the behavior for deleting the snapshots on this blob. {@code Include} will delete the base blob + * and all snapshots. {@code Only} will delete only the snapshots. If a snapshot is being deleted, you must + * pass null. * @param accessConditions - * {@link BlobAccessConditions} - * @return - * Emits the successful response. + * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_delete + * "Sample code for BlobURL.delete")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single delete( - DeleteSnapshotsOptionType deleteBlobSnapshotOptions, BlobAccessConditions accessConditions) { + public Single delete(DeleteSnapshotsOptionType deleteBlobSnapshotOptions, + BlobAccessConditions accessConditions, Context context) { accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlobs().deleteWithRestResponseAsync( - null, null, - accessConditions.getLeaseAccessConditions().getLeaseId(), - deleteBlobSnapshotOptions, - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context, null, null, deleteBlobSnapshotOptions, null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** - * Returns the blob's metadata and properties. For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=properties_metadata "Sample code for BlobURL.getProperties")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Returns the blob's metadata and properties. For more information, see the Azure Docs. * * @param accessConditions - * {@link BlobAccessConditions} - * @return - * Emits the successful response. + * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=properties_metadata + * "Sample code for BlobURL.getProperties")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single getProperties( - BlobAccessConditions accessConditions) { + public Single getProperties(BlobAccessConditions accessConditions, Context context) { accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlobs().getPropertiesWithRestResponseAsync( - null, null, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context, null, null, null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** - * Changes a blob's HTTP header properties. For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=properties_metadata "Sample code for BlobURL.setHTTPHeaders")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Changes a blob's HTTP header properties. For more information, see the Azure + * Docs. * * @param headers * {@link BlobHTTPHeaders} * @param accessConditions - * {@link BlobAccessConditions} - * @return - * Emits the successful response. + * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=properties_metadata + * "Sample code for BlobURL.setHTTPHeaders")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single setHTTPHeaders( - BlobHTTPHeaders headers, BlobAccessConditions accessConditions) { - headers = headers == null ? BlobHTTPHeaders.NONE : headers; + public Single setHTTPHeaders(BlobHTTPHeaders headers, + BlobAccessConditions accessConditions, Context context) { accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlobs().setHTTPHeadersWithRestResponseAsync( - null, - headers.getCacheControl(), - headers.getContentType(), - headers.getContentMD5(), - headers.getContentEncoding(), - headers.getContentLanguage(), - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - headers.getContentDisposition(), - null)); + context, null, null, headers, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** - * Changes a blob's metadata. For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=properties_metadata "Sample code for BlobURL.setMetadata")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Changes a blob's metadata. For more information, see the Azure + * Docs. * * @param metadata - * {@link Metadata} + * {@link Metadata} * @param accessConditions - * {@link BlobAccessConditions} - * @return - * Emits the successful response. + * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=properties_metadata + * "Sample code for BlobURL.setMetadata")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single setMetadata( - Metadata metadata, BlobAccessConditions accessConditions) { + public Single setMetadata(Metadata metadata, BlobAccessConditions accessConditions, + Context context) { metadata = metadata == null ? Metadata.NONE : metadata; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlobs().setMetadataWithRestResponseAsync( - null, metadata, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context, null, metadata, null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** - * Creates a read-only snapshot of a blob. For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=snapshot "Sample code for BlobURL.createSnapshot")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Creates a read-only snapshot of a blob. For more information, see the Azure + * Docs. * * @param metadata - * {@link Metadata} + * {@link Metadata} * @param accessConditions - * {@link BlobAccessConditions} - * @return - * Emits the successful response. + * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @return Emits the successful response. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=snapshot + * "Sample code for BlobURL.createSnapshot")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single createSnapshot( - Metadata metadata, BlobAccessConditions accessConditions) { + public Single createSnapshot(Metadata metadata, BlobAccessConditions accessConditions, + Context context) { metadata = metadata == null ? Metadata.NONE : metadata; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlobs().createSnapshotWithRestResponseAsync( - null, metadata, - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - accessConditions.getLeaseAccessConditions().getLeaseId(), - null)); + context, null, metadata, null, accessConditions.modifiedAccessConditions(), + accessConditions.leaseAccessConditions())); } /** * Sets the tier on a blob. The operation is allowed on a page blob in a premium storage account or a block blob in * a blob storage or GPV2 account. A premium page blob's tier determines the allowed size, IOPS, and bandwidth of * the blob. A block blob's tier determines the Hot/Cool/Archive storage type. This does not update the blob's etag. + * For detailed information about block blob level tiering see the Azure Docs. * * @apiNote - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=tier "Sample code for BlobURL.setTier")] + * ## Sample Code \n + * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=tier "Sample code for BlobURL.setTier")] \n + * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * * @param tier * The new tier for the blob. + * @param leaseAccessConditions + * {@link LeaseAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single setTier(AccessTier tier) { + public Single setTier(AccessTier tier, LeaseAccessConditions leaseAccessConditions, + Context context) { Utility.assertNotNull("tier", tier); + context = context == null ? Context.NONE : context; - return addErrorWrappingToSingle(this.storageClient.generatedBlobs().setTierWithRestResponseAsync(tier, - null,null)); + return addErrorWrappingToSingle(this.storageClient.generatedBlobs().setTierWithRestResponseAsync(context, tier, + null, null, leaseAccessConditions)); } /** * Undelete restores the content and metadata of a soft-deleted blob and/or any associated soft-deleted snapshots. - * For more information, see the Azure Docs. + * For more information, see the Azure + * Docs. * * @apiNote - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=undelete "Sample code for BlobURL.undelete")] + * ## Sample Code \n + * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=undelete "Sample code for BlobURL.undelete")] \n + * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * * @return * Emits the successful response. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. */ - public Single undelete() { - return addErrorWrappingToSingle(this.storageClient.generatedBlobs().undeleteWithRestResponseAsync(null, + public Single undelete(Context context) { + context = context == null ? Context.NONE : context; + + return addErrorWrappingToSingle(this.storageClient.generatedBlobs().undeleteWithRestResponseAsync(context, null, null)); } /** - * Acquires a lease on the blob for write and delete operations. The lease duration must be between - * 15 to 60 seconds, or infinite (-1). For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease "Sample code for BlobURL.acquireLease")]\n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Acquires a lease on the blob for write and delete operations. The lease duration must be between 15 to 60 + * seconds, or infinite (-1). For more information, see the Azure + * Docs. * * @param proposedID - * A {@code String} in any valid GUID format. May be null. + * A {@code String} in any valid GUID format. May be null. * @param duration * The duration of the lease, in seconds, or negative one (-1) for a lease that * never expires. A non-infinite lease can be between 15 and 60 seconds. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single acquireLease( - String proposedID, int duration, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; + public Single acquireLease(String proposedID, int duration, + ModifiedAccessConditions modifiedAccessConditions, Context context) { if (!(duration == -1 || (duration >= 15 && duration <=60))) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException("Duration must be -1 or between 15 and 60."); } + context = context == null ? Context.NONE : context; - return addErrorWrappingToSingle(this.storageClient.generatedBlobs().acquireLeaseWithRestResponseAsync( - null, duration, proposedID, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - httpAccessConditions.getIfMatch().toString(), - httpAccessConditions.getIfNoneMatch().toString(), - null)); + return addErrorWrappingToSingle(this.storageClient.generatedBlobs().acquireLeaseWithRestResponseAsync(context, + null, duration, proposedID, null, modifiedAccessConditions)); } /** - * Renews the blob's previously-acquired lease. For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease "Sample code for BlobURL.renewLease")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Renews the blob's previously-acquired lease. For more information, see the Azure Docs. * * @param leaseID * The leaseId of the active lease on the blob. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single renewLease( - String leaseID, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - - return addErrorWrappingToSingle(this.storageClient.generatedBlobs().renewLeaseWithRestResponseAsync( - leaseID, null, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - httpAccessConditions.getIfMatch().toString(), - httpAccessConditions.getIfNoneMatch().toString(), - null)); + public Single renewLease(String leaseID, ModifiedAccessConditions modifiedAccessConditions, + Context context) { + context = context == null ? Context.NONE : context; + + return addErrorWrappingToSingle(this.storageClient.generatedBlobs().renewLeaseWithRestResponseAsync(context, + leaseID, null, null, modifiedAccessConditions)); } /** - * Releases the blob's previously-acquired lease. For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease "Sample code for BlobURL.releaseLease")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * Releases the blob's previously-acquired lease. For more information, see the Azure Docs. * * @param leaseID - * The leaseId of the active lease on the blob. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * The leaseId of the active lease on the blob. + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + *@param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease + * "Sample code for BlobURL.releaseLease")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * @return * Emits the successful response. */ - public Single releaseLease( - String leaseID, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - - return addErrorWrappingToSingle(this.storageClient.generatedBlobs().releaseLeaseWithRestResponseAsync( - leaseID, null, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - httpAccessConditions.getIfMatch().toString(), - httpAccessConditions.getIfNoneMatch().toString(), - null)); + public Single releaseLease(String leaseID, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + context = context == null ? Context.NONE : context; + + return addErrorWrappingToSingle(this.storageClient.generatedBlobs().releaseLeaseWithRestResponseAsync(context, + leaseID, null, null, modifiedAccessConditions)); } /** @@ -550,79 +553,87 @@ public Single releaseLease( * to break a fixed-duration lease when it expires or an infinite lease immediately. For more information, see the * Azure Docs. * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease "Sample code for BlobURL.breakLease")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) - * * @param breakPeriodInSeconds * An optional {@code Integer} representing the proposed duration of seconds that the lease should continue * before it is broken, between 0 and 60 seconds. This break period is only used if it is shorter than the time * remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be * available before the break period has expired, but the lease may be held for longer than the break period. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + *@param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * + * @apiNote ## Sample Code \n + * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease "Sample code for BlobURL.breakLease")] \n + * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * * @return * Emits the successful response. */ - public Single breakLease( - Integer breakPeriodInSeconds, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - - return addErrorWrappingToSingle(this.storageClient.generatedBlobs().breakLeaseWithRestResponseAsync( - null, breakPeriodInSeconds, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - httpAccessConditions.getIfMatch().toString(), - httpAccessConditions.getIfNoneMatch().toString(), - null)); + public Single breakLease(Integer breakPeriodInSeconds, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + context = context == null ? Context.NONE : context; + + return addErrorWrappingToSingle(this.storageClient.generatedBlobs().breakLeaseWithRestResponseAsync(context, + null, breakPeriodInSeconds, null, modifiedAccessConditions)); } /** - * ChangeLease changes the blob's lease ID. For more information, see the - * Azure Docs. - * - * @apiNote - * ## Sample Code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease "Sample code for BlobURL.changeLease")] \n - * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) + * ChangeLease changes the blob's lease ID. For more information, see the Azure + * Docs. * * @param leaseId - * The leaseId of the active lease on the blob. + * The leaseId of the active lease on the blob. * @param proposedID - * A {@code String} in any valid GUID format. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * A {@code String} in any valid GUID format. + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + *@param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * + * @apiNote ## Sample Code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blob_lease + * "Sample code for BlobURL.changeLease")] \n For more samples, please see the [Samples + * file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * @return * Emits the successful response. */ - public Single changeLease( - String leaseId, String proposedID, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - - return addErrorWrappingToSingle(this.storageClient.generatedBlobs().changeLeaseWithRestResponseAsync( - leaseId, proposedID, null, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - httpAccessConditions.getIfMatch().toString(), httpAccessConditions.getIfNoneMatch().toString(), - null)); + public Single changeLease(String leaseId, String proposedID, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + context = context == null ? Context.NONE : context; + + return addErrorWrappingToSingle(this.storageClient.generatedBlobs().changeLeaseWithRestResponseAsync(context, + leaseId, proposedID, null, null, modifiedAccessConditions)); } /** - * Returns the sku name and account kind for the account. For more information, please see the - * Azure Docs. - * - * @apiNote - * ## Sample code \n - * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=account_info "Sample code for BlobURL.getAccountInfo")] \n - * For more samples, please see the [Samples file] (https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) - * - * @return - * Emits the successful response. + * Returns the sku name and account kind for the account. For more information, please see the Azure Docs. + * + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * + * @return Emits the successful response. + * @apiNote ## Sample code \n [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=account_info + * "Sample code for BlobURL.getAccountInfo")] \n For more samples, please see the [Samples file] + * (https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) */ - public Single getAccountInfo() { + public Single getAccountInfo(Context context) { + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle( - this.storageClient.generatedBlobs().getAccountInfoWithRestResponseAsync()); + this.storageClient.generatedBlobs().getAccountInfoWithRestResponseAsync(context)); } // TODO: Update links diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlobURLParts.java b/src/main/java/com/microsoft/azure/storage/blob/BlobURLParts.java index 4db68bdd5b31..e43ee1494b52 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/BlobURLParts.java +++ b/src/main/java/com/microsoft/azure/storage/blob/BlobURLParts.java @@ -34,43 +34,128 @@ */ public final class BlobURLParts { + private String scheme; + + private String host; + + private String containerName; + + private String blobName; + + private String snapshot; + + private SASQueryParameters sasQueryParameters; + + private Map unparsedParameters; + /** * The scheme. Ex: "https://". */ - public String scheme; + public String scheme() { + return scheme; + } + + /** + * The scheme. Ex: "https://". + */ + public BlobURLParts withScheme(String scheme) { + this.scheme = scheme; + return this; + } /** * The host. Ex: "account.blob.core.windows.net". */ - public String host; + public String host() { + return host; + } + + /** + * The host. Ex: "account.blob.core.windows.net". + */ + public BlobURLParts withHost(String host) { + this.host = host; + return this; + } /** * The container name or {@code null} if a {@link ServiceURL} was parsed. */ - public String containerName; + public String containerName() { + return containerName; + } + + /** + * The container name or {@code null} if a {@link ServiceURL} was parsed. + */ + public BlobURLParts withContainerName(String containerName) { + this.containerName = containerName; + return this; + } + + /** + * The blob name or {@code null} if a {@link ServiceURL} or {@link ContainerURL} was parsed. + */ + public String blobName() { + return blobName; + } /** * The blob name or {@code null} if a {@link ServiceURL} or {@link ContainerURL} was parsed. */ - public String blobName; + public BlobURLParts withBlobName(String blobName) { + this.blobName = blobName; + return this; + } /** * The snapshot time or {@code null} if anything except a URL to a snapshot was parsed. */ - public String snapshot; + public String snapshot() { + return snapshot; + } + + /** + * The snapshot time or {@code null} if anything except a URL to a snapshot was parsed. + */ + public BlobURLParts withSnapshot(String snapshot) { + this.snapshot = snapshot; + return this; + } /** * A {@link SASQueryParameters} representing the SAS query parameters or {@code null} if there were no such * parameters. */ - public SASQueryParameters sasQueryParameters; + public SASQueryParameters sasQueryParameters() { + return sasQueryParameters; + } + + /** + * A {@link SASQueryParameters} representing the SAS query parameters or {@code null} if there were no such + * parameters. + */ + public BlobURLParts withSasQueryParameters(SASQueryParameters sasQueryParameters) { + this.sasQueryParameters = sasQueryParameters; + return this; + } /** * The query parameter key value pairs aside from SAS parameters and snapshot time or {@code null} if there were * no such parameters. */ - public Map unparsedParameters; + public Map unparsedParameters() { + return unparsedParameters; + } + /** + * The query parameter key value pairs aside from SAS parameters and snapshot time or {@code null} if there were + * no such parameters. + */ + public BlobURLParts withUnparsedParameters(Map unparsedParameters) { + this.unparsedParameters = unparsedParameters; + return this; + } /** * Initializes a BlobURLParts object with all fields set to null, except unparsedParameters, which is an empty map. diff --git a/src/main/java/com/microsoft/azure/storage/blob/BlockBlobURL.java b/src/main/java/com/microsoft/azure/storage/blob/BlockBlobURL.java index ab34758bdbda..cc7ac5ebb698 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/BlockBlobURL.java +++ b/src/main/java/com/microsoft/azure/storage/blob/BlockBlobURL.java @@ -15,6 +15,7 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.*; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.http.HttpPipeline; import io.reactivex.Flowable; import io.reactivex.Single; @@ -93,7 +94,7 @@ public BlockBlobURL withPipeline(HttpPipeline pipeline) { */ public BlockBlobURL withSnapshot(String snapshot) throws MalformedURLException, UnknownHostException { BlobURLParts blobURLParts = URLParser.parse(new URL(this.storageClient.url())); - blobURLParts.snapshot = snapshot; + blobURLParts.withSnapshot(snapshot); return new BlockBlobURL(blobURLParts.toURL(), super.storageClient.httpPipeline()); } @@ -105,6 +106,9 @@ public BlockBlobURL withSnapshot(String snapshot) throws MalformedURLException, * For more information, see the * Azure Docs. * + * Note that the data passed must be replayable if retries are enabled (the default). In other words, the + * {@code Flowable} must produce the same data each time it is subscribed to. + * * For more efficient bulk-upload scenarios, please refer to the {@link TransferManager} for convenience methods. * * @apiNote @@ -113,7 +117,8 @@ public BlockBlobURL withSnapshot(String snapshot) throws MalformedURLException, * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * * @param data - * The data to write to the blob. + * The data to write to the blob. Note that this {@code Flowable} must be replayable if retries are enabled + * (the default). In other words, the Flowable must produce the same data each time it is subscribed to. * @param length * The exact length of the data. It is important that this value match precisely the length of the data * emitted by the {@code Flowable}. @@ -123,30 +128,25 @@ public BlockBlobURL withSnapshot(String snapshot) throws MalformedURLException, * {@link Metadata} * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ public Single upload( Flowable data, long length, BlobHTTPHeaders headers, Metadata metadata, - BlobAccessConditions accessConditions) { - headers = headers == null ? BlobHTTPHeaders.NONE : headers; + BlobAccessConditions accessConditions, Context context) { metadata = metadata == null ? Metadata.NONE : metadata; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; - return addErrorWrappingToSingle(this.storageClient.generatedBlockBlobs().uploadWithRestResponseAsync( - data, length, null, - headers.getContentType(), - headers.getContentEncoding(), - headers.getContentLanguage(), - headers.getContentMD5(), - headers.getCacheControl(), - metadata, - accessConditions.getLeaseAccessConditions().getLeaseId(), - headers.getContentDisposition(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context = context == null ? Context.NONE : context; + + return addErrorWrappingToSingle(this.storageClient.generatedBlockBlobs().uploadWithRestResponseAsync(context, + data, length, null, metadata, null, headers, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** @@ -154,6 +154,9 @@ public Single upload( * commitBlockList. For more information, see the * Azure Docs. * + * Note that the data passed must be replayable if retries are enabled (the default). In other words, the + * {@code Flowable} must produce the same data each time it is subscribed to. + * * @apiNote * ## Sample Code \n * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=blocks "Sample code for BlockBlobURL.stageBlock")] \n @@ -163,21 +166,28 @@ public Single upload( * A Base64 encoded {@code String} that specifies the ID for this block. Note that all block ids for a given * blob must be the same length. * @param data - * The data to write to the block. + * The data to write to the block. Note that this {@code Flowable} must be replayable if retries are enabled + * (the default). In other words, the Flowable must produce the same data each time it is subscribed to. * @param length * The exact length of the data. It is important that this value match precisely the length of the data * emitted by the {@code Flowable}. * @param leaseAccessConditions * {@link LeaseAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single stageBlock( - String base64BlockID, Flowable data, long length, LeaseAccessConditions leaseAccessConditions) { - leaseAccessConditions = leaseAccessConditions == null ? LeaseAccessConditions.NONE : leaseAccessConditions; + public Single stageBlock(String base64BlockID, Flowable data, long length, + LeaseAccessConditions leaseAccessConditions, Context context) { + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlockBlobs().stageBlockWithRestResponseAsync( - base64BlockID, length, data,null, leaseAccessConditions.getLeaseId(), null)); + context, base64BlockID, length, data, null, null, null, leaseAccessConditions)); } /** @@ -202,19 +212,25 @@ public Single stageBlock( * the received data and fail the request if it does not match the provided MD5. * @param leaseAccessConditions * {@link LeaseAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single stageBlockFromURL( - String base64BlockID, URL sourceURL, BlobRange sourceRange, byte[] sourceContentMD5, - LeaseAccessConditions leaseAccessConditions) { - leaseAccessConditions = leaseAccessConditions == null ? LeaseAccessConditions.NONE : leaseAccessConditions; + public Single stageBlockFromURL(String base64BlockID, URL sourceURL, + BlobRange sourceRange, byte[] sourceContentMD5, LeaseAccessConditions leaseAccessConditions, + Context context) { sourceRange = sourceRange == null ? BlobRange.DEFAULT : sourceRange; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle( - this.storageClient.generatedBlockBlobs().stageBlockFromURLWithRestResponseAsync( + this.storageClient.generatedBlockBlobs().stageBlockFromURLWithRestResponseAsync(context, base64BlockID, 0, sourceURL, sourceRange.toString(), sourceContentMD5, - null, leaseAccessConditions.getLeaseId(), null)); + null, null, leaseAccessConditions)); } /** @@ -231,15 +247,21 @@ public Single stageBlockFromURL( * Specifies which type of blocks to return. * @param leaseAccessConditions * {@link LeaseAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getBlockList( - BlockListType listType, LeaseAccessConditions leaseAccessConditions) { - leaseAccessConditions = leaseAccessConditions == null ? LeaseAccessConditions.NONE : leaseAccessConditions; + public Single getBlockList(BlockListType listType, + LeaseAccessConditions leaseAccessConditions, Context context) { + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedBlockBlobs().getBlockListWithRestResponseAsync( - listType, null, null, leaseAccessConditions.getLeaseId(), null)); + context, listType, null, null, null, leaseAccessConditions)); } /** @@ -266,29 +288,25 @@ public Single getBlockList( * {@link Metadata} * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single commitBlockList( - List base64BlockIDs, BlobHTTPHeaders headers, Metadata metadata, - BlobAccessConditions accessConditions) { - headers = headers == null ? BlobHTTPHeaders.NONE : headers; + public Single commitBlockList(List base64BlockIDs, + BlobHTTPHeaders headers, Metadata metadata, BlobAccessConditions accessConditions, Context context) { metadata = metadata == null ? Metadata.NONE : metadata; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle(this.storageClient.generatedBlockBlobs().commitBlockListWithRestResponseAsync( - new BlockLookupList().withLatest(base64BlockIDs), null, - headers.getCacheControl(), - headers.getContentType(), - headers.getContentEncoding(), - headers.getContentLanguage(), - headers.getContentMD5(), - metadata, - accessConditions.getLeaseAccessConditions().getLeaseId(), - headers.getContentDisposition(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), null)); + context, new BlockLookupList().withLatest(base64BlockIDs), null, + metadata, null, headers, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } //TODO: stageBlockFromURL diff --git a/src/main/java/com/microsoft/azure/storage/blob/Constants.java b/src/main/java/com/microsoft/azure/storage/blob/Constants.java index 519f6fd8c917..7207f382028f 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/Constants.java +++ b/src/main/java/com/microsoft/azure/storage/blob/Constants.java @@ -121,7 +121,7 @@ static final class HeaderConstants { /** * Specifies the value to use for UserAgent header. */ - static final String USER_AGENT_VERSION = "10.0.4-rc"; + static final String USER_AGENT_VERSION = "10.1.0"; private HeaderConstants() { // Private to prevent construction. diff --git a/src/main/java/com/microsoft/azure/storage/blob/ContainerAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/ContainerAccessConditions.java index 6f7696fa234e..11801277e28d 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ContainerAccessConditions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ContainerAccessConditions.java @@ -14,6 +14,9 @@ */ package com.microsoft.azure.storage.blob; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; + /** * This class contains values which will restrict the successful operation of a variety of requests to the conditions * present. These conditions are entirely optional. The entire object or any of its properties may be set to null when @@ -25,39 +28,44 @@ public final class ContainerAccessConditions { /** * An object representing no access conditions. */ - public static final ContainerAccessConditions NONE = new ContainerAccessConditions(null, - null); + public static final ContainerAccessConditions NONE = new ContainerAccessConditions(); - private final HTTPAccessConditions httpAccessConditions; + private ModifiedAccessConditions modifiedAccessConditions; - private final LeaseAccessConditions leaseID; + private LeaseAccessConditions leaseAccessConditions; /** - * Creates a {@link ContainerAccessConditions} object. - * - * @param httpAccessConditions - * An {@link HTTPAccessConditions} object. - * @param leaseID - * A {@link LeaseAccessConditions} object. + * {@link ModifiedAccessConditions} */ - public ContainerAccessConditions(HTTPAccessConditions httpAccessConditions, LeaseAccessConditions leaseID) { - this.httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - this.leaseID = leaseID == null ? LeaseAccessConditions.NONE : leaseID; + public ModifiedAccessConditions modifiedAccessConditions() { + return modifiedAccessConditions; } /** - * @return - * A {@link HTTPAccessConditions} object + * {@link ModifiedAccessConditions} */ - public HTTPAccessConditions getHttpAccessConditions() { - return httpAccessConditions; + public ContainerAccessConditions withModifiedAccessConditions(ModifiedAccessConditions modifiedAccessConditions) { + this.modifiedAccessConditions = modifiedAccessConditions; + return this; } /** - * @return - * A {@link LeaseAccessConditions} object + * {@link LeaseAccessConditions} */ - public LeaseAccessConditions getLeaseAccessConditions() { - return leaseID; + public LeaseAccessConditions leaseAccessConditions() { + return leaseAccessConditions; + } + + /** + * {@link LeaseAccessConditions} + */ + public ContainerAccessConditions withLeaseAccessConditions(LeaseAccessConditions leaseID) { + this.leaseAccessConditions = leaseID; + return this; + } + + public ContainerAccessConditions() { + this.modifiedAccessConditions = new ModifiedAccessConditions(); + this.leaseAccessConditions = new LeaseAccessConditions(); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/ContainerListingDetails.java b/src/main/java/com/microsoft/azure/storage/blob/ContainerListingDetails.java index 92fbe3112319..c02fb5d11f81 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ContainerListingDetails.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ContainerListingDetails.java @@ -27,26 +27,27 @@ public final class ContainerListingDetails { /** * An object indicating that no extra details should be returned. */ - public static final ContainerListingDetails NONE = new ContainerListingDetails(false); + public static final ContainerListingDetails NONE = new ContainerListingDetails(); - private final boolean metadata; + private boolean metadata; + + public ContainerListingDetails() { + + } /** - * A {@link ContainerListingDetails} object. - * - * @param metadata - * Whether metadata should be returned. + * Whether metadata should be returned. */ - public ContainerListingDetails(boolean metadata) { - this.metadata = metadata; + public boolean metadata() { + return this.metadata; } /** - * @return - * Whether metadata should be returned. + * Whether metadata should be returned. */ - public boolean getMetadata() { - return this.metadata; + public ContainerListingDetails withMetadata(boolean metadata) { + this.metadata = metadata; + return this; } /* diff --git a/src/main/java/com/microsoft/azure/storage/blob/ContainerSASPermission.java b/src/main/java/com/microsoft/azure/storage/blob/ContainerSASPermission.java index ce59284e4a01..bd50b25d07c4 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ContainerSASPermission.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ContainerSASPermission.java @@ -25,35 +25,107 @@ * the order of the permissions is particular and this class guarantees correctness. */ public final class ContainerSASPermission { + private boolean read; + + private boolean add; + + private boolean create; + + private boolean write; + + private boolean delete; + + private boolean list; + /** * Specifies Read access granted. */ - public boolean read; + public boolean read() { + return read; + } + + /** + * Specifies Read access granted. + */ + public ContainerSASPermission withRead(boolean read) { + this.read = read; + return this; + } + + /** + * Specifies Add access granted. + */ + public boolean add() { + return add; + } /** * Specifies Add access granted. */ - public boolean add; + public ContainerSASPermission withAdd(boolean add) { + this.add = add; + return this; + } + + /** + * Specifies Create access granted. + */ + public boolean create() { + return create; + } /** * Specifies Create access granted. */ - public boolean create; + public ContainerSASPermission withCreate(boolean create) { + this.create = create; + return this; + } /** * Specifies Write access granted. */ - public boolean write; + public boolean write() { + return write; + } + + /** + * Specifies Write access granted. + */ + public ContainerSASPermission withWrite(boolean write) { + this.write = write; + return this; + } /** * Specifies Delete access granted. */ - public boolean delete; + public boolean delete() { + return delete; + } + + /** + * Specifies Delete access granted. + */ + public ContainerSASPermission withDelete(boolean delete) { + this.delete = delete; + return this; + } + + /** + * Specifies List access granted. + */ + public boolean list() { + return list; + } /** * Specifies List access granted. */ - public boolean list; + public ContainerSASPermission withList(boolean list) { + this.list = list; + return this; + } /** * Initializes an {@code ContainerSASPermssion} object with all fields set to false. diff --git a/src/main/java/com/microsoft/azure/storage/blob/ContainerURL.java b/src/main/java/com/microsoft/azure/storage/blob/ContainerURL.java index 92a35f3b03e4..e33d383e141f 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ContainerURL.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ContainerURL.java @@ -15,6 +15,7 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.*; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.http.HttpPipeline; import io.reactivex.Single; @@ -177,14 +178,21 @@ public BlobURL createBlobURL(String blobName) { * @param accessType * Specifies how the data in this container is available to the public. See the x-ms-blob-public-access header * in the Azure Docs for more information. Pass null for no public access. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single create( - Metadata metadata, PublicAccessType accessType) { + public Single create(Metadata metadata, PublicAccessType accessType, Context context) { metadata = metadata == null ? Metadata.NONE : metadata; + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle(this.storageClient.generatedContainers().createWithRestResponseAsync( - null, metadata, accessType, null)); + context, null, metadata, accessType, null)); } @@ -200,26 +208,28 @@ public Single create( * * @param accessConditions * {@link ContainerAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single delete( - ContainerAccessConditions accessConditions) { + public Single delete(ContainerAccessConditions accessConditions, Context context) { accessConditions = accessConditions == null ? ContainerAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; - if (!accessConditions.getHttpAccessConditions().getIfMatch().equals(ETag.NONE) || - !accessConditions.getHttpAccessConditions().getIfNoneMatch().equals(ETag.NONE)) { + if (!validateNoEtag(accessConditions.modifiedAccessConditions())) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException("ETag access conditions are not supported for this API."); } return addErrorWrappingToSingle(this.storageClient.generatedContainers() - .deleteWithRestResponseAsync(null, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - null)); + .deleteWithRestResponseAsync(context, null, null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** @@ -233,16 +243,21 @@ public Single delete( * * @param leaseAccessConditions * {@link LeaseAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getProperties( - LeaseAccessConditions leaseAccessConditions) { - leaseAccessConditions = leaseAccessConditions == null ? LeaseAccessConditions.NONE : leaseAccessConditions; + public Single getProperties(LeaseAccessConditions leaseAccessConditions, + Context context) { + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers() - .getPropertiesWithRestResponseAsync(null, - leaseAccessConditions.getLeaseId(), null)); + .getPropertiesWithRestResponseAsync(context, null, null, leaseAccessConditions)); } /** @@ -258,16 +273,22 @@ public Single getProperties( * {@link Metadata} * @param accessConditions * {@link ContainerAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single setMetadata( - Metadata metadata, ContainerAccessConditions accessConditions) { + public Single setMetadata(Metadata metadata, + ContainerAccessConditions accessConditions, Context context) { metadata = metadata == null ? Metadata.NONE : metadata; accessConditions = accessConditions == null ? ContainerAccessConditions.NONE : accessConditions; - if (accessConditions.getHttpAccessConditions().getIfMatch() != ETag.NONE || - accessConditions.getHttpAccessConditions().getIfNoneMatch() != ETag.NONE || - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince() != null) { + context = context == null ? Context.NONE : context; + if (!validateNoEtag(accessConditions.modifiedAccessConditions()) || + accessConditions.modifiedAccessConditions().ifUnmodifiedSince() != null) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException( @@ -275,9 +296,8 @@ public Single setMetadata( } return addErrorWrappingToSingle(this.storageClient.generatedContainers() - .setMetadataWithRestResponseAsync(null, - accessConditions.getLeaseAccessConditions().getLeaseId(), metadata, - accessConditions.getHttpAccessConditions().getIfModifiedSince(),null)); + .setMetadataWithRestResponseAsync(context, null, metadata, null, + accessConditions.leaseAccessConditions(), accessConditions.modifiedAccessConditions())); } /** @@ -292,15 +312,21 @@ public Single setMetadata( * * @param leaseAccessConditions * {@link LeaseAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getAccessPolicy( - LeaseAccessConditions leaseAccessConditions) { - leaseAccessConditions = leaseAccessConditions == null ? LeaseAccessConditions.NONE : leaseAccessConditions; + public Single getAccessPolicy(LeaseAccessConditions leaseAccessConditions, + Context context) { + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers().getAccessPolicyWithRestResponseAsync( - null, leaseAccessConditions.getLeaseId(), null)); + context, null, null, leaseAccessConditions)); } /** @@ -323,16 +349,21 @@ public Single getAccessPolicy( * for more information. Passing null will clear all access policies. * @param accessConditions * {@link ContainerAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single setAccessPolicy( - PublicAccessType accessType, List identifiers, - ContainerAccessConditions accessConditions) { + public Single setAccessPolicy(PublicAccessType accessType, + List identifiers, ContainerAccessConditions accessConditions, Context context) { accessConditions = accessConditions == null ? ContainerAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; - if (!accessConditions.getHttpAccessConditions().getIfMatch().equals(ETag.NONE) || - !accessConditions.getHttpAccessConditions().getIfNoneMatch().equals(ETag.NONE)) { + if (!validateNoEtag(accessConditions.modifiedAccessConditions())) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException("ETag access conditions are not supported for this API."); @@ -359,16 +390,15 @@ OffsetDateTime.now will only give back milliseconds (more precise fields are zer // TODO: validate that empty list clears permissions and null list does not change list. Document behavior. return addErrorWrappingToSingle(this.storageClient.generatedContainers() - .setAccessPolicyWithRestResponseAsync(identifiers, null, - accessConditions.getLeaseAccessConditions().getLeaseId(), accessType, - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - null)); + .setAccessPolicyWithRestResponseAsync(context, identifiers, null, accessType, null, + accessConditions.leaseAccessConditions(), accessConditions.modifiedAccessConditions())); } - private boolean validateLeaseOperationAccessConditions(HTTPAccessConditions httpAccessConditions) { - return (httpAccessConditions.getIfMatch() == ETag.NONE && - httpAccessConditions.getIfNoneMatch() == ETag.NONE); + private boolean validateNoEtag(ModifiedAccessConditions modifiedAccessConditions) { + if (modifiedAccessConditions == null) { + return true; + } + return modifiedAccessConditions.ifMatch() == null && modifiedAccessConditions.ifNoneMatch() == null; } /** @@ -386,26 +416,30 @@ private boolean validateLeaseOperationAccessConditions(HTTPAccessConditions http * @param duration * The duration of the lease, in seconds, or negative one (-1) for a lease that never expires. * A non-infinite lease can be between 15 and 60 seconds. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * * @return * Emits the successful response. */ - public Single acquireLease( - String proposedID, int duration, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - if (!this.validateLeaseOperationAccessConditions(httpAccessConditions)){ + public Single acquireLease(String proposedID, int duration, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + if (!this.validateNoEtag(modifiedAccessConditions)){ // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException( "ETag access conditions are not supported for this API."); } + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers().acquireLeaseWithRestResponseAsync( - null, duration, proposedID, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - null)); + context, null, duration, proposedID, null, modifiedAccessConditions)); } /** @@ -419,26 +453,29 @@ public Single acquireLease( * * @param leaseID * The leaseId of the active lease on the container. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single renewLease( - String leaseID, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - if (!this.validateLeaseOperationAccessConditions(httpAccessConditions)) { + public Single renewLease(String leaseID, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + if (!this.validateNoEtag(modifiedAccessConditions)) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException( "ETag access conditions are not supported for this API."); } + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers().renewLeaseWithRestResponseAsync( - leaseID, null, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - null)); + context, leaseID, null, null, modifiedAccessConditions)); } /** @@ -452,26 +489,29 @@ public Single renewLease( * * @param leaseID * The leaseId of the active lease on the container. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single releaseLease( - String leaseID, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - if (!this.validateLeaseOperationAccessConditions(httpAccessConditions)) { + public Single releaseLease(String leaseID, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + if (!this.validateNoEtag(modifiedAccessConditions)) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException( "ETag access conditions are not supported for this API."); } + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers().releaseLeaseWithRestResponseAsync( - leaseID, null, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - null)); + context, leaseID, null, null, modifiedAccessConditions)); } /** @@ -488,30 +528,33 @@ public Single releaseLease( * before it is broken, between 0 and 60 seconds. This break period is only used if it is shorter than the time * remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be * available before the break period has expired, but the lease may be held for longer than the break period. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} * @return * Emits the successful response. */ - public Single breakLease( - Integer breakPeriodInSeconds, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - if (!this.validateLeaseOperationAccessConditions(httpAccessConditions)) { + public Single breakLease(Integer breakPeriodInSeconds, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + if (!this.validateNoEtag(modifiedAccessConditions)) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException( "ETag access conditions are not supported for this API."); } + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers().breakLeaseWithRestResponseAsync( - null, breakPeriodInSeconds, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - null)); + context, null, breakPeriodInSeconds, null, modifiedAccessConditions)); } /** - * Changes the container's leaseID. For more information, see the + * Changes the container's leaseAccessConditions. For more information, see the * Azure Docs. * * @apiNote @@ -523,26 +566,30 @@ public Single breakLease( * The leaseId of the active lease on the container. * @param proposedID * A {@code String} in any valid GUID format. - * @param httpAccessConditions - * {@link HTTPAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * * @return * Emits the successful response. */ - public Single changeLease( - String leaseID, String proposedID, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; - if (!this.validateLeaseOperationAccessConditions(httpAccessConditions)) { + public Single changeLease(String leaseID, String proposedID, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + if (!this.validateNoEtag(modifiedAccessConditions)) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException( "ETag access conditions are not supported for this API."); } + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers().changeLeaseWithRestResponseAsync( - leaseID, proposedID, null, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - null)); + context, leaseID, proposedID, null, null, modifiedAccessConditions)); } /** @@ -564,17 +611,24 @@ public Single changeLease( * ListBlobsFlatSegmentResponse.body().nextMarker(). Set to null to list the first segment. * @param options * {@link ListBlobsOptions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single listBlobsFlatSegment( - String marker, ListBlobsOptions options) { + public Single listBlobsFlatSegment(String marker, ListBlobsOptions options, + Context context) { options = options == null ? ListBlobsOptions.DEFAULT : options; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers() - .listBlobFlatSegmentWithRestResponseAsync( - options.getPrefix(), marker, options.getMaxResults(), - options.getDetails().toList(), null, null)); + .listBlobFlatSegmentWithRestResponseAsync(context, + options.prefix(), marker, options.maxResults(), + options.details().toList(), null, null)); } /** @@ -600,20 +654,27 @@ public Single listBlobsFlatSegment( * be a single character or a string. * @param options * {@link ListBlobsOptions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single listBlobsHierarchySegment( - String marker, String delimiter, ListBlobsOptions options) { + public Single listBlobsHierarchySegment(String marker, String delimiter, + ListBlobsOptions options, Context context) { options = options == null ? ListBlobsOptions.DEFAULT : options; - if (options.getDetails().getSnapshots()) { + if (options.details().snapshots()) { throw new IllegalArgumentException("Including snapshots in a hierarchical listing is not supported."); } + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedContainers() .listBlobHierarchySegmentWithRestResponseAsync( - delimiter, options.getPrefix(), marker, options.getMaxResults(), - options.getDetails().toList(), null, null)); + context, delimiter, options.prefix(), marker, options.maxResults(), + options.details().toList(), null, null)); } /** @@ -625,11 +686,19 @@ public Single listBlobsHierarchySegme * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=account_info "Sample code for ContainerURL.getAccountInfo")] \n * For more samples, please see the [Samples file] (https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getAccountInfo() { + public Single getAccountInfo(Context context) { + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle( - this.storageClient.generatedContainers().getAccountInfoWithRestResponseAsync()); + this.storageClient.generatedContainers().getAccountInfoWithRestResponseAsync(context)); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/DownloadResponse.java b/src/main/java/com/microsoft/azure/storage/blob/DownloadResponse.java index cbc433a21544..401d5ffa9cc6 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/DownloadResponse.java +++ b/src/main/java/com/microsoft/azure/storage/blob/DownloadResponse.java @@ -16,84 +16,126 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.BlobDownloadHeaders; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; import com.microsoft.rest.v2.RestResponse; -import com.microsoft.rest.v2.http.HttpRequest; +import com.microsoft.rest.v2.http.HttpPipeline; import io.reactivex.Flowable; import io.reactivex.Single; -import io.reactivex.internal.functions.Functions; +import io.reactivex.functions.Function; -import java.io.Closeable; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.Map; /** * {@code DownloadResponse} wraps the protocol-layer response from {@link BlobURL#download(BlobRange, - * BlobAccessConditions, boolean)} to help provide information for retrying. + * BlobAccessConditions, boolean, com.microsoft.rest.v2.Context)} to automatically retry failed reads from the body as + * appropriate. If the download is interrupted, the {@code DownloadResponse} will make a request to resume the download + * from where it left off, allowing the user to consume the data as one continuous stream, for any interruptions are + * hidden. The retry behavior is defined by the options passed to the {@link #body(ReliableDownloadOptions)}. The + * download will also lock on the blob's etag to ensure consistency. + *

+ * Note that the retries performed as a part of this reader are composed with those of any retries in an {@link + * HttpPipeline} used in conjunction with this reader. That is, if this object issues a request to resume a download, + * an underlying pipeline may issue several retries as a part of that request. Furthermore, this reader only retries on + * network errors; timeouts and unexpected status codes are not retried. Therefore, the behavior of this reader is + * entirely independent of and in no way coupled to an {@link HttpPipeline}'s retry mechanism. */ -public class DownloadResponse extends RestResponse> implements Closeable { - private BlobURL blobURL; +public final class DownloadResponse { + private final HTTPGetterInfo info; - private RetryReader.HTTPGetterInfo info; + private final RestResponse> rawResponse; - DownloadResponse(HttpRequest request, BlobURL blobURL, RetryReader.HTTPGetterInfo info, int statusCode, - BlobDownloadHeaders blobsDownloadHeaders, Map rawHeaders, - Flowable byteBufferFlowable) { - super(request, statusCode, blobsDownloadHeaders, rawHeaders, byteBufferFlowable); + private final Function> getter; - this.blobURL = blobURL; + public DownloadResponse(RestResponse> response, + HTTPGetterInfo info, Function> getter) { + Utility.assertNotNull("getter", getter); + Utility.assertNotNull("info", info); + Utility.assertNotNull("info.eTag", info.eTag()); + this.rawResponse = response; this.info = info; + this.getter = getter; } /** - * Constructs a new {@link RetryReader} stream for reliably reading data if desired (if {@code options != null} and - * {@code options.maxRetryRequests > 0}. If retries are enabled, if a connection fails while reading, the {@code - * RetryReader} will make additional requests to reestablish a connection and continue reading. + * Returns the response body which has been modified to enable reliably reading data if desired (if + * {@code options.maxRetryRequests > 0}. If retries are enabled, if a connection fails while reading, the stream + * will make additional requests to reestablish a connection and continue reading. * * @param options - * {@link RetryReaderOptions} + * {@link ReliableDownloadOptions} * @return A {@code Flowable} which emits the data as {@code ByteBuffer}s. */ - public Flowable body(RetryReaderOptions options) { - options = options == null ? new RetryReaderOptions() : options; - if (options.maxRetryRequests == 0) { - return super.body(); + public Flowable body(ReliableDownloadOptions options) { + ReliableDownloadOptions optionsReal = options == null ? new ReliableDownloadOptions() : options; + if (optionsReal.maxRetryRequests() == 0) { + return this.rawResponse.body(); + } + + return this.rawResponse.body() + /* + Update how much data we have received in case we need to retry and propagate to the user the data we + have received. + */ + .doOnNext(buffer -> { + this.info.withOffset(this.info.offset() + buffer.remaining()); + if (info.count() != null) { + this.info.withCount(this.info.count() - buffer.remaining()); + } + }) + .onErrorResumeNext(throwable -> { + // So far we have tried once but retried zero times. + return tryContinueFlowable(throwable, 0, optionsReal); + }); + } + + private Flowable tryContinueFlowable(Throwable t, int retryCount, ReliableDownloadOptions options) { + // If all the errors are exhausted, return this error to the user. + if (retryCount > options.maxRetryRequests() || !(t instanceof IOException)) { + return Flowable.error(t); + } + else { + try { + // Get a new response and try reading from it. + return getter.apply(this.info) + .flatMapPublisher(response ->{ + // Do not compound the number of retries; just get the raw body. + ReliableDownloadOptions newOptions = new ReliableDownloadOptions() + .withMaxRetryRequests(0); + + return response.body(newOptions) + .doOnNext(buffer -> { + this.info.withOffset(this.info.offset() + buffer.remaining()); + if (info.count() != null) { + this.info.withCount(this.info.count() - buffer.remaining()); + } + }) + .onErrorResumeNext(t2 -> { + // Increment the retry count and try again with the new exception. + return tryContinueFlowable(t2, retryCount + 1, options); + }); + }); + } catch (Exception e) { + // If the getter fails, return the getter failure to the user. + return Flowable.error(e); + } } - return new RetryReader(Single.just(this), this.info, options, - newInfo -> this.blobURL.download(new BlobRange(newInfo.offset, newInfo.count), new BlobAccessConditions( - new HTTPAccessConditions(null, null, info.eTag, null), - null, null, null), - false)); } - @Override public int statusCode() { - return super.statusCode(); + return this.rawResponse.statusCode(); } - @Override public BlobDownloadHeaders headers() { - return super.headers(); + return this.rawResponse.headers(); } - @Override public Map rawHeaders() { - return super.rawHeaders(); + return this.rawResponse.rawHeaders(); } - /** - * Equivalent to calling {@link #body(RetryReaderOptions)} with {@code null}. - */ - @Override - public Flowable body() { - return this.body(null); - } - - /** - * Disposes of the connection associated with this stream response. - */ - @Override - public void close() { - // Taken from BlobsDownloadResponse. - body().subscribe(Functions.emptyConsumer(), Functions.emptyConsumer()).dispose(); + public RestResponse> rawResponse() { + return this.rawResponse; } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/ETag.java b/src/main/java/com/microsoft/azure/storage/blob/ETag.java deleted file mode 100644 index cfd8cb1e99c1..000000000000 --- a/src/main/java/com/microsoft/azure/storage/blob/ETag.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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; - -/** - * An HTTP ETag. An object of this type may be set as a field on an {@link HTTPAccessConditions} object to specify that - * a request should use ETag conditions. Null may be passed if no ETag condition is required. - */ -public final class ETag { - - private final String eTagString; - - /** - * Used for matching with no ETag. - */ - public static final ETag NONE = new ETag(null); - - /** - * Used for matching with any ETag. - */ - public static final ETag ANY = new ETag("*"); - - /** - * Creates a {@link ETag} object. - * - * @param eTagString - * The {@code String} to convert to an ETag. - */ - public ETag(String eTagString) { - this.eTagString = eTagString; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ETag)) { - return false; - } - if (this.eTagString == null) { - return ((ETag) obj).eTagString == null; - } - return this.eTagString.equals(((ETag)obj).eTagString); - } - - @Override - public String toString() { - if (this.equals(ETag.NONE)) { - return null; - } - return this.eTagString; - } -} diff --git a/src/main/java/com/microsoft/azure/storage/blob/HTTPAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/HTTPAccessConditions.java deleted file mode 100644 index 42d83b46d911..000000000000 --- a/src/main/java/com/microsoft/azure/storage/blob/HTTPAccessConditions.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 java.time.OffsetDateTime; - -/** - * This type contains standard HTTP Access Conditions. Some methods do take this structure on its own, but it is most - * commonly used as a member of {@link BlobAccessConditions} or {@link ContainerAccessConditions}. Specifying these - * conditions is entirely optional, and null may be passed for this structure or any individual field to indicate that - * none of the conditions should be set. Please refer to the - * Azure Docs - * for more information. - */ -public final class HTTPAccessConditions { - - /** - * An object representing no access conditions. - */ - public static final HTTPAccessConditions NONE = new HTTPAccessConditions(null, null, - null, null); - - private final OffsetDateTime ifModifiedSince; - - private final OffsetDateTime ifUnmodifiedSince; - - private final ETag ifMatch; - - private final ETag ifNoneMatch; - - /** - * Creates a {@code HTTPAccessConditions} object. - * - * @param ifModifiedSince - * The HTTP If-Modified-Since access condition. - * @param ifUnmodifiedSince - * The HTTP If-Unmodified-Since access condition. - * @param ifMatch - * An ETag for the HTTP If-Match access condition. - * @param ifNoneMatch - * An ETag for the HTTP If-None-Match access condition. - */ - public HTTPAccessConditions(OffsetDateTime ifModifiedSince, OffsetDateTime ifUnmodifiedSince, ETag ifMatch, - ETag ifNoneMatch) { - this.ifModifiedSince = ifModifiedSince; - this.ifUnmodifiedSince = ifUnmodifiedSince; - - this.ifMatch = ifMatch == null ? ETag.NONE : ifMatch; - this.ifNoneMatch = ifNoneMatch == null ? ETag.NONE : ifNoneMatch; - } - - /** - * @return - * If not null, operations will only succeed if the object has been modified since this time. - */ - public OffsetDateTime getIfModifiedSince() { - return ifModifiedSince; - } - - /** - * @return - * If not null, operations will only succeed if the object has been unmodified since this time. - */ - public OffsetDateTime getIfUnmodifiedSince() { - return ifUnmodifiedSince; - } - - /** - * @return - * If not null, operations will only succeed if the object's etag matches this value. - */ - public ETag getIfMatch() { - return ifMatch; - } - - /** - * @return - * If not null, operations will only succeed if the object's etag does not match this value. - */ - public ETag getIfNoneMatch() { - return ifNoneMatch; - } -} diff --git a/src/main/java/com/microsoft/azure/storage/blob/HTTPGetterInfo.java b/src/main/java/com/microsoft/azure/storage/blob/HTTPGetterInfo.java new file mode 100644 index 000000000000..7985b476b70f --- /dev/null +++ b/src/main/java/com/microsoft/azure/storage/blob/HTTPGetterInfo.java @@ -0,0 +1,82 @@ +/* + * 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; + +/** + * HTTPGetterInfo is a passed to the getter function of a reliable download to specify parameters needed for the GET + * request. + */ +public final class HTTPGetterInfo { + private long offset = 0; + + private Long count = null; + + private String eTag = null; + + /** + * The start offset that should be used when creating the HTTP GET request's Range header. Defaults to 0. + */ + public long offset() { + return offset; + } + + /** + * The start offset that should be used when creating the HTTP GET request's Range header. Defaults to 0. + */ + public HTTPGetterInfo withOffset(long offset) { + this.offset = offset; + return this; + } + + /** + * The count of bytes that should be used to calculate the end offset when creating the HTTP GET request's Range + * header. {@code} null is the default and indicates that the entire rest of the blob should be retrieved. + */ + public Long count() { + return count; + } + + /** + * The count of bytes that should be used to calculate the end offset when creating the HTTP GET request's Range + * header. {@code} null is the default and indicates that the entire rest of the blob should be retrieved. + */ + public HTTPGetterInfo withCount(Long count) { + if (count != null) { + Utility.assertInBounds("count", count, 0, Integer.MAX_VALUE); + } + this.count = count; + return this; + } + + /** + * The resource's etag that should be used when creating the HTTP GET request's If-Match header. Note that the + * Etag is returned with any operation that modifies the resource and by a call to {@link + * BlobURL#getProperties(BlobAccessConditions, com.microsoft.rest.v2.Context)}. Defaults to null. + */ + public String eTag() { + return eTag; + } + + /** + * The resource's etag that should be used when creating the HTTP GET request's If-Match header. Note that the + * Etag is returned with any operation that modifies the resource and by a call to {@link + * BlobURL#getProperties(BlobAccessConditions, com.microsoft.rest.v2.Context)}. Defaults to null. + */ + public HTTPGetterInfo withETag(String eTag) { + this.eTag = eTag; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/microsoft/azure/storage/blob/IPRange.java b/src/main/java/com/microsoft/azure/storage/blob/IPRange.java index 59d22ae34b2d..c60aa93b98f9 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/IPRange.java +++ b/src/main/java/com/microsoft/azure/storage/blob/IPRange.java @@ -26,15 +26,39 @@ public final class IPRange { public static final IPRange DEFAULT = new IPRange(); + private String ipMin; + + private String ipMax; + + /** + * A {@link Inet4Address} representing the minimum IP address of the range. + */ + public String ipMin() { + return ipMin; + } + /** * A {@link Inet4Address} representing the minimum IP address of the range. */ - public String ipMin; + public IPRange withIpMin(String ipMin) { + this.ipMin = ipMin; + return this; + } /** * A {@link Inet4Address} representing the maximum IP address of the range. */ - public String ipMax; + public String ipMax() { + return ipMax; + } + + /** + * A {@link Inet4Address} representing the maximum IP address of the range. + */ + public IPRange withIpMax(String ipMax) { + this.ipMax = ipMax; + return this; + } public IPRange() { } diff --git a/src/main/java/com/microsoft/azure/storage/blob/LeaseAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/LeaseAccessConditions.java deleted file mode 100644 index ad7a1c0d280f..000000000000 --- a/src/main/java/com/microsoft/azure/storage/blob/LeaseAccessConditions.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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; - -/** - * By specifying a leaseID as a member of this class, operations on storage resources will only succeed if the active - * lease on the blob matches the string contained here. Some methods do take this structure on its own, but it is most - * commonly used as a member of {@link BlobAccessConditions} or {@link ContainerAccessConditions}. Specifying these - * conditions is entirely optional, and null may be passed for this structure or any individual field to indicate that - * none of the conditions should be set. Please refer to the - * Azure Docs - * for more information. - * - */ -public final class LeaseAccessConditions { - - /** - * An object representing no lease access conditions. - */ - public static final LeaseAccessConditions NONE = new LeaseAccessConditions(null); - - private final String leaseId; - - /** - * Creates a {@link LeaseAccessConditions} object. - * - * @param leaseId - * A {@code String} representing the lease access conditions for a container or blob. - */ - public LeaseAccessConditions(String leaseId) { - this.leaseId = leaseId; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof LeaseAccessConditions)){ - return false; - } - if (this.leaseId == null) { - return ((LeaseAccessConditions) obj).leaseId == null; - } - return this.leaseId.equals(obj); - } - - /** - * @return - * The id of the lease. - */ - public String getLeaseId() { - return this.leaseId; - } -} diff --git a/src/main/java/com/microsoft/azure/storage/blob/ListBlobsOptions.java b/src/main/java/com/microsoft/azure/storage/blob/ListBlobsOptions.java index 8ddc7e31f1c4..280352def0e1 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ListBlobsOptions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ListBlobsOptions.java @@ -24,60 +24,69 @@ public final class ListBlobsOptions { * An object representing the default options: no details, prefix, or delimiter. Uses the server default for * maxResults. */ - public static final ListBlobsOptions DEFAULT = new ListBlobsOptions(BlobListingDetails.NONE, null, - null); + public static final ListBlobsOptions DEFAULT = new ListBlobsOptions(); - private final BlobListingDetails details; + private BlobListingDetails details; - private final String prefix; + private String prefix; - private final Integer maxResults; + private Integer maxResults; /** - * An object filled with the specified values. - * - * @param details - * {@link BlobListingDetails} - * @param prefix - * Filters the results to return only blobs whose names begin with the specified prefix. May be null to return - * all blobs. - * @param maxResults - * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not - * specify maxResults or specifies a value greater than 5,000, the server will return up to 5,000 items. + * {@link BlobListingDetails} */ - public ListBlobsOptions(BlobListingDetails details, String prefix, Integer maxResults) { - if (maxResults != null && maxResults <= 0) { - throw new IllegalArgumentException("MaxResults must be greater than 0."); - } - this.details = details == null ? BlobListingDetails.NONE : details; - this.prefix = prefix; - this.maxResults = maxResults; + public BlobListingDetails details() { + return details; + } + + /** + * {@link BlobListingDetails} + */ + public ListBlobsOptions withDetails(BlobListingDetails details) { + this.details = details; + return this; + } + + /** + * Filters the results to return only blobs whose names begin with the specified prefix. May be null to return + * all blobs. + */ + public String prefix() { + return prefix; } /** - * @return - * {@link BlobListingDetails} + * Filters the results to return only blobs whose names begin with the specified prefix. May be null to return + * all blobs. */ - public BlobListingDetails getDetails() { - return this.details; + public ListBlobsOptions withPrefix(String prefix) { + this.prefix = prefix; + return this; } /** - * @return - * Filters the results to return only blobs whose names begin with the specified - * prefix. + * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not + * specify maxResults or specifies a value greater than 5,000, the server will return up to 5,000 items. */ - public String getPrefix() { - return this.prefix; + public Integer maxResults() { + return maxResults; } /** - * @return - * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does - * not specify maxresults or specifies a value greater than 5,000, the server will return up to 5,000 - * items. + * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not + * specify maxResults or specifies a value greater than 5,000, the server will return up to 5,000 items. */ - public Integer getMaxResults() { - return this.maxResults; + public ListBlobsOptions withMaxResults(Integer maxResults) { + if (maxResults != null && maxResults <= 0) { + throw new IllegalArgumentException("MaxResults must be greater than 0."); + } + this.maxResults = maxResults; + return this; + } + + public ListBlobsOptions() { + this.details = BlobListingDetails.NONE; } + + } diff --git a/src/main/java/com/microsoft/azure/storage/blob/ListContainersOptions.java b/src/main/java/com/microsoft/azure/storage/blob/ListContainersOptions.java index ce1071e3dc30..bda5f2adef36 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ListContainersOptions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ListContainersOptions.java @@ -25,56 +25,65 @@ public final class ListContainersOptions { * An object representing the default options: no details or prefix and using the service's default for maxResults. */ public static final ListContainersOptions DEFAULT = - new ListContainersOptions(new ContainerListingDetails(false),null, null); + new ListContainersOptions(); - private final ContainerListingDetails details; + private ContainerListingDetails details; - private final String prefix; + private String prefix; - private final Integer maxResults; + private Integer maxResults; /** - * A {@link ListContainersOptions} object. - * - * @param details - * {@link ContainerListingDetails} - * @param prefix - * Filters the results to return only blobs whose names begin with the specified prefix. - * @param maxResults - * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not - * specify maxResults or specifies a value greater than 5,000, the server will return up to 5,000 items. + * {@link ContainerListingDetails} */ - public ListContainersOptions(ContainerListingDetails details, String prefix, Integer maxResults) { - if (maxResults != null && maxResults <= 0) { - throw new IllegalArgumentException("MaxResults must be greater than 0."); - } - this.details = details == null ? ContainerListingDetails.NONE : details; - this.prefix = prefix; - this.maxResults = maxResults; + public ContainerListingDetails details() { + return details; + } + + /** + * {@link ContainerListingDetails} + */ + public ListContainersOptions withDetails(ContainerListingDetails details) { + this.details = details; + return this; + } + + /** + * Filters the results to return only blobs whose names begin with the specified prefix. * + */ + public String prefix() { + return prefix; } /** - * @return - * {@link ContainerListingDetails} + * Filters the results to return only blobs whose names begin with the specified prefix. * */ - public ContainerListingDetails getDetails() { - return this.details; + public ListContainersOptions withPrefix(String prefix) { + this.prefix = prefix; + return this; } /** - * @return - * Filters the results to return only blobs whose names begin with the specified prefix. + * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not + * specify maxResults or specifies a value greater than 5,000, the server will return up to 5,000 items. */ - public String getPrefix() { - return this.prefix; + public Integer maxResults() { + return maxResults; } /** - * @return - * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not - * specify maxResults or specifies a value greater than 5,000, the server will return up to 5,000 items. + * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not + * specify maxResults or specifies a value greater than 5,000, the server will return up to 5,000 items. */ - public Integer getMaxResults() { - return this.maxResults; + public ListContainersOptions withMaxResults(Integer maxResults) { + if (maxResults != null && maxResults <= 0) { + throw new IllegalArgumentException("MaxResults must be greater than 0."); + } + this.maxResults = maxResults; + return this; + } + + public ListContainersOptions() { + this.details = ContainerListingDetails.NONE; } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/LoggingFactory.java b/src/main/java/com/microsoft/azure/storage/blob/LoggingFactory.java index d24c58639e7f..efef3f98dd8a 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/LoggingFactory.java +++ b/src/main/java/com/microsoft/azure/storage/blob/LoggingFactory.java @@ -128,13 +128,13 @@ public Single sendAsync(final HttpRequest request) { // If the response took too long, we'll upgrade to warning. if (requestCompletionTime >= - factory.loggingOptions.getMinDurationToLogSlowRequestsInMs()) { + factory.loggingOptions.minDurationToLogSlowRequestsInMs()) { // Log a warning if the try duration exceeded the specified threshold. if (options.shouldLog(HttpPipelineLogLevel.WARNING)) { currentLevel = HttpPipelineLogLevel.WARNING; logMessage = String.format(Locale.ROOT, "SLOW OPERATION. Duration > %d ms.%n", - factory.loggingOptions.getMinDurationToLogSlowRequestsInMs()); + factory.loggingOptions.minDurationToLogSlowRequestsInMs()); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/LoggingOptions.java b/src/main/java/com/microsoft/azure/storage/blob/LoggingOptions.java index 13a011fa8c1d..c41cf3b67f06 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/LoggingOptions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/LoggingOptions.java @@ -45,7 +45,7 @@ public LoggingOptions(long minDurationToLogSlowRequestsInMs) { * @return * The duration after which a tried operation will be logged as a warning. */ - public long getMinDurationToLogSlowRequestsInMs() { + public long minDurationToLogSlowRequestsInMs() { return minDurationToLogSlowRequestsInMs; } diff --git a/src/main/java/com/microsoft/azure/storage/blob/PageBlobAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/PageBlobAccessConditions.java index 1f6d9ef5d6bb..c43c3d2f559d 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/PageBlobAccessConditions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/PageBlobAccessConditions.java @@ -14,10 +14,13 @@ */ package com.microsoft.azure.storage.blob; +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; +import com.microsoft.azure.storage.blob.models.SequenceNumberAccessConditions; + /** * This class contains values that restrict the successful completion of PageBlob operations to certain conditions. - * An instance of this class is set as a member of {@link BlobAccessConditions} when needed. It may also be set to null - * if no access conditions are desired. + * It may be set to null if no access conditions are desired. * * Please refer to the request header section * here for more conceptual information. @@ -27,47 +30,62 @@ public final class PageBlobAccessConditions { /** * An object representing no access conditions. */ - public static final PageBlobAccessConditions NONE = new PageBlobAccessConditions(null, - null, null); + public static final PageBlobAccessConditions NONE = new PageBlobAccessConditions(); - private final Long ifSequenceNumberLessThan; + private SequenceNumberAccessConditions sequenceNumberAccessConditions; - private final Long ifSequenceNumberLessThanOrEqual; + private ModifiedAccessConditions modifiedAccessConditions; - private final Long ifSequenceNumberEqual; + private LeaseAccessConditions leaseAccessConditions; /** - * Creates a set of conditions under which a request to a PageBlob will succeed. - * - * @param ifSequenceNumberLessThan - * Ensures that the page blob operation succeeds only if the blob's sequence number is less than a value. - * @param ifSequenceNumberLessThanOrEqual - * Ensures that the page blob operation succeeds only if the blob's sequence number is less than or equal to a - * value. - * @param ifSequenceNumberEqual - * Ensures that the page blob operation succeeds only if the blob's sequence number is equal to a value. + * {@link SequenceNumberAccessConditions} */ - public PageBlobAccessConditions(Long ifSequenceNumberLessThan, Long ifSequenceNumberLessThanOrEqual, - Long ifSequenceNumberEqual) { - if ((ifSequenceNumberEqual != null && ifSequenceNumberEqual < -1) || - (ifSequenceNumberLessThan != null && ifSequenceNumberLessThan < -1) || - (ifSequenceNumberLessThanOrEqual != null && ifSequenceNumberLessThanOrEqual < -1)) { - throw new IllegalArgumentException("Sequence number access conditions cannot be less than -1"); - } - this.ifSequenceNumberLessThan = ifSequenceNumberLessThan; - this.ifSequenceNumberLessThanOrEqual = ifSequenceNumberLessThanOrEqual; - this.ifSequenceNumberEqual = ifSequenceNumberEqual; + public SequenceNumberAccessConditions sequenceNumberAccessConditions() { + return sequenceNumberAccessConditions; } - public Long getIfSequenceNumberLessThan() { - return ifSequenceNumberLessThan; + /** + * {@link SequenceNumberAccessConditions} + */ + public PageBlobAccessConditions withSequenceNumberAccessConditions(SequenceNumberAccessConditions sequenceNumberAccessConditions) { + this.sequenceNumberAccessConditions = sequenceNumberAccessConditions; + return this; } - public Long getIfSequenceNumberLessThanOrEqual() { - return ifSequenceNumberLessThanOrEqual; + /** + * {@link ModifiedAccessConditions} + */ + public ModifiedAccessConditions modifiedAccessConditions() { + return modifiedAccessConditions; + } + + /** + * {@link ModifiedAccessConditions} + */ + public PageBlobAccessConditions withModifiedAccessConditions(ModifiedAccessConditions modifiedAccessConditions) { + this.modifiedAccessConditions = modifiedAccessConditions; + return this; + } + + /** + * {@link LeaseAccessConditions} + */ + public LeaseAccessConditions leaseAccessConditions() { + return leaseAccessConditions; + } + + /** + * {@link LeaseAccessConditions} + */ + public PageBlobAccessConditions withLeaseAccessConditions(LeaseAccessConditions leaseAccessConditions) { + this.leaseAccessConditions = leaseAccessConditions; + return this; } - public Long getIfSequenceNumberEqual() { - return ifSequenceNumberEqual; + public PageBlobAccessConditions() { + this.sequenceNumberAccessConditions = new SequenceNumberAccessConditions(); + this.modifiedAccessConditions = new ModifiedAccessConditions(); + this.leaseAccessConditions = new LeaseAccessConditions(); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/PageBlobURL.java b/src/main/java/com/microsoft/azure/storage/blob/PageBlobURL.java index f3e8cc2954ab..0111b70705b2 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/PageBlobURL.java +++ b/src/main/java/com/microsoft/azure/storage/blob/PageBlobURL.java @@ -15,6 +15,7 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.*; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.http.HttpPipeline; import com.microsoft.rest.v2.http.UrlBuilder; import io.reactivex.Flowable; @@ -88,7 +89,7 @@ public PageBlobURL withPipeline(HttpPipeline pipeline) { */ public PageBlobURL withSnapshot(String snapshot) throws MalformedURLException, UnknownHostException { BlobURLParts blobURLParts = URLParser.parse(new URL(this.storageClient.url())); - blobURLParts.snapshot = snapshot; + blobURLParts.withSnapshot(snapshot); return new PageBlobURL(blobURLParts.toURL(), super.storageClient.httpPipeline()); } @@ -114,12 +115,19 @@ public PageBlobURL withSnapshot(String snapshot) throws MalformedURLException, U * {@link Metadata} * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single create( - long size, Long sequenceNumber, BlobHTTPHeaders headers, Metadata metadata, - BlobAccessConditions accessConditions) { + public Single create(long size, Long sequenceNumber, BlobHTTPHeaders headers, + Metadata metadata, BlobAccessConditions accessConditions, Context context) { + accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + if (size%PageBlobURL.PAGE_BYTES != 0) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. @@ -130,26 +138,13 @@ public Single create( // subscription. throw new IllegalArgumentException("SequenceNumber must be greater than or equal to 0."); } - headers = headers == null ? BlobHTTPHeaders.NONE : headers; metadata = metadata == null ? Metadata.NONE : metadata; - accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; // TODO: What if you pass 0 for pageblob size? Validate? return addErrorWrappingToSingle(this.storageClient.generatedPageBlobs().createWithRestResponseAsync( - 0, size, null, - headers.getContentType(), - headers.getContentEncoding(), - headers.getContentLanguage(), - headers.getContentMD5(), - headers.getCacheControl(), - metadata, - accessConditions.getLeaseAccessConditions().getLeaseId(), - headers.getContentDisposition(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - sequenceNumber, null)); + context, 0, size, null, metadata, sequenceNumber, null, headers, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** @@ -157,6 +152,9 @@ public Single create( * For more information, see the * Azure Docs. * + * Note that the data passed must be replayable if retries are enabled (the default). In other words, the + * {@code Flowable} must produce the same data each time it is subscribed to. + * * @apiNote * ## Sample Code \n * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=page_blob_basic "Sample code for PageBlobURL.uploadPages")] \n @@ -167,32 +165,37 @@ public Single create( * be a modulus of 512 and the end offset must be a modulus of 512 - 1. Examples of valid byte ranges are * 0-511, 512-1023, etc. * @param body - * The data to upload. - * @param accessConditions - * {@link BlobAccessConditions} + * The data to upload. Note that this {@code Flowable} must be replayable if retries are enabled + * (the default). In other words, the Flowable must produce the same data each time it is subscribed to. + * @param pageBlobAccessConditions + * {@link PageBlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single uploadPages( - PageRange pageRange, Flowable body, BlobAccessConditions accessConditions) { - accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + public Single uploadPages(PageRange pageRange, Flowable body, + PageBlobAccessConditions pageBlobAccessConditions, Context context) { + pageBlobAccessConditions = pageBlobAccessConditions == null ? PageBlobAccessConditions.NONE : + pageBlobAccessConditions; + if (pageRange == null) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException("pageRange cannot be null."); } String pageRangeStr = pageRangeToString(pageRange); + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedPageBlobs().uploadPagesWithRestResponseAsync( - body, pageRange.end()-pageRange.start()+1, null, pageRangeStr, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getPageBlobAccessConditions().getIfSequenceNumberLessThanOrEqual(), - accessConditions.getPageBlobAccessConditions().getIfSequenceNumberLessThan(), - accessConditions.getPageBlobAccessConditions().getIfSequenceNumberEqual(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), null)); + context, body, pageRange.end()-pageRange.start()+1, null, null, pageRangeStr, null, + pageBlobAccessConditions.leaseAccessConditions(), + pageBlobAccessConditions.sequenceNumberAccessConditions(), + pageBlobAccessConditions.modifiedAccessConditions())); } /** @@ -209,31 +212,33 @@ public Single uploadPages( * A {@link PageRange} object. Given that pages must be aligned with 512-byte boundaries, the start offset must * be a modulus of 512 and the end offset must be a modulus of 512 - 1. Examples of valid byte ranges are * 0-511, 512-1023, etc. - * @param accessConditions - * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. + * @param pageBlobAccessConditions + * {@link PageBlobAccessConditions} * @return * Emits the successful response. */ - public Single clearPages( - PageRange pageRange, BlobAccessConditions accessConditions) { - accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + public Single clearPages(PageRange pageRange, + PageBlobAccessConditions pageBlobAccessConditions, Context context) { + pageBlobAccessConditions = pageBlobAccessConditions == null ? PageBlobAccessConditions.NONE : + pageBlobAccessConditions; if (pageRange == null) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException("pageRange cannot be null."); } String pageRangeStr = pageRangeToString(pageRange); + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedPageBlobs().clearPagesWithRestResponseAsync( - 0,null, pageRangeStr, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getPageBlobAccessConditions().getIfSequenceNumberLessThanOrEqual(), - accessConditions.getPageBlobAccessConditions().getIfSequenceNumberLessThan(), - accessConditions.getPageBlobAccessConditions().getIfSequenceNumberEqual(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), null)); + context, 0, null, pageRangeStr, null, pageBlobAccessConditions.leaseAccessConditions(), + pageBlobAccessConditions.sequenceNumberAccessConditions(), + pageBlobAccessConditions.modifiedAccessConditions())); } /** @@ -249,22 +254,24 @@ public Single clearPages( * {@link BlobRange} * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getPageRanges( - BlobRange blobRange, BlobAccessConditions accessConditions) { + public Single getPageRanges(BlobRange blobRange, + BlobAccessConditions accessConditions, Context context) { blobRange = blobRange == null ? BlobRange.DEFAULT : blobRange; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedPageBlobs().getPageRangesWithRestResponseAsync( - null, null, blobRange.toString(), - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context, null, null, blobRange.toString(), null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** @@ -284,26 +291,28 @@ public Single getPageRanges( * blob may be a snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getPageRangesDiff( - BlobRange blobRange, String prevSnapshot, BlobAccessConditions accessConditions) { + public Single getPageRangesDiff(BlobRange blobRange, String prevSnapshot, + BlobAccessConditions accessConditions, Context context) { blobRange = blobRange == null ? BlobRange.DEFAULT : blobRange; accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; if (prevSnapshot == null) { throw new IllegalArgumentException("prevSnapshot cannot be null"); } return addErrorWrappingToSingle(this.storageClient.generatedPageBlobs().getPageRangesDiffWithRestResponseAsync( - null,null, prevSnapshot, blobRange.toString(), - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context, null, null, prevSnapshot, blobRange.toString(), null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** @@ -320,26 +329,27 @@ public Single getPageRangesDiff( * blob, then all pages above the specified value are cleared. * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single resize( - long size, BlobAccessConditions accessConditions) { + public Single resize(long size, BlobAccessConditions accessConditions, Context context) { if (size%PageBlobURL.PAGE_BYTES != 0) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException("size must be a multiple of PageBlobURL.PAGE_BYTES."); } accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle(this.storageClient.generatedPageBlobs().resizeWithRestResponseAsync( - size,null, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - null)); + context, size, null, null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** @@ -358,30 +368,30 @@ public Single resize( * requests and manage concurrency issues. * @param accessConditions * {@link BlobAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single updateSequenceNumber( - SequenceNumberActionType action, Long sequenceNumber, BlobAccessConditions accessConditions) { + public Single updateSequenceNumber(SequenceNumberActionType action, + Long sequenceNumber, BlobAccessConditions accessConditions, Context context) { if (sequenceNumber != null && sequenceNumber < 0) { // Throwing is preferred to Single.error because this will error out immediately instead of waiting until // subscription. throw new IllegalArgumentException("SequenceNumber must be greater than or equal to 0."); } accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; - if(action == SequenceNumberActionType.INCREMENT) { - sequenceNumber = null; - } + sequenceNumber = action == SequenceNumberActionType.INCREMENT ? null : sequenceNumber; + context = context == null ? Context.NONE : context; return addErrorWrappingToSingle( - this.storageClient.generatedPageBlobs().updateSequenceNumberWithRestResponseAsync( - action, null, - accessConditions.getLeaseAccessConditions().getLeaseId(), - accessConditions.getHttpAccessConditions().getIfModifiedSince(), - accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - accessConditions.getHttpAccessConditions().getIfMatch().toString(), - accessConditions.getHttpAccessConditions().getIfNoneMatch().toString(), - sequenceNumber,null)); + this.storageClient.generatedPageBlobs().updateSequenceNumberWithRestResponseAsync(context, + action, null, sequenceNumber, null, accessConditions.leaseAccessConditions(), + accessConditions.modifiedAccessConditions())); } /** @@ -396,14 +406,20 @@ public Single updateSequenceNumber( * The source page blob. * @param snapshot * The snapshot on the copy source. - * @param httpAccessConditions - * {@link BlobAccessConditions} + * @param modifiedAccessConditions + * {@link ModifiedAccessConditions} + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single copyIncremental( - URL source, String snapshot, HTTPAccessConditions httpAccessConditions) { - httpAccessConditions = httpAccessConditions == null ? HTTPAccessConditions.NONE : httpAccessConditions; + public Single copyIncremental(URL source, String snapshot, + ModifiedAccessConditions modifiedAccessConditions, Context context) { + context = context == null ? Context.NONE : context; UrlBuilder builder = UrlBuilder.parse(source); builder.setQueryParameter(Constants.SNAPSHOT_QUERY_PARAMETER, snapshot); @@ -414,11 +430,7 @@ public Single copyIncremental( throw new Error(e); } return addErrorWrappingToSingle(this.storageClient.generatedPageBlobs().copyIncrementalWithRestResponseAsync( - source, null, null, - httpAccessConditions.getIfModifiedSince(), - httpAccessConditions.getIfUnmodifiedSince(), - httpAccessConditions.getIfMatch().toString(), - httpAccessConditions.getIfNoneMatch().toString(), null)); + context, source, null, null, modifiedAccessConditions)); } private static String pageRangeToString(PageRange pageRange) { diff --git a/src/main/java/com/microsoft/azure/storage/blob/PipelineOptions.java b/src/main/java/com/microsoft/azure/storage/blob/PipelineOptions.java index 5569c260d01a..0ddf5e676e85 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/PipelineOptions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/PipelineOptions.java @@ -36,30 +36,90 @@ public final class PipelineOptions { must not be passed to anything with a longer lifetime. */ + private HttpClient client; + + private HttpPipelineLogger logger; + + private RequestRetryOptions requestRetryOptions = RequestRetryOptions.DEFAULT; + + private LoggingOptions loggingOptions = LoggingOptions.DEFAULT; + + private TelemetryOptions telemetryOptions = TelemetryOptions.DEFAULT; + + /** + * Specifies which HttpClient to use to send the requests. + */ + public HttpClient client() { + return client; + } + /** * Specifies which HttpClient to use to send the requests. */ - public HttpClient client; + public PipelineOptions withClient(HttpClient client) { + this.client = client; + return this; + } /** * Specifies the logger for the pipeline. */ - public HttpPipelineLogger logger; + public HttpPipelineLogger logger() { + return logger; + } + + /** + * Specifies the logger for the pipeline. + */ + public PipelineOptions withLogger(HttpPipelineLogger logger) { + this.logger = logger; + return this; + } /** * Configures the retry policy's behavior. */ - public RequestRetryOptions requestRetryOptions = RequestRetryOptions.DEFAULT; + public RequestRetryOptions requestRetryOptions() { + return requestRetryOptions; + } + + /** + * Configures the retry policy's behavior. + */ + public PipelineOptions withRequestRetryOptions(RequestRetryOptions requestRetryOptions) { + this.requestRetryOptions = requestRetryOptions; + return this; + } /** * Configures the built-in request logging policy. */ - public LoggingOptions loggingOptions = LoggingOptions.DEFAULT; + public LoggingOptions loggingOptions() { + return loggingOptions; + } + + /** + * Configures the built-in request logging policy. + */ + public PipelineOptions withLoggingOptions(LoggingOptions loggingOptions) { + this.loggingOptions = loggingOptions; + return this; + } + + /** + * Configures the built-in telemetry policy behavior. + */ + public TelemetryOptions telemetryOptions() { + return telemetryOptions; + } /** * Configures the built-in telemetry policy behavior. */ - public TelemetryOptions telemetryOptions = TelemetryOptions.DEFAULT; + public PipelineOptions withTelemetryOptions(TelemetryOptions telemetryOptions) { + this.telemetryOptions = telemetryOptions; + return this; + } /** * Returns a {@code PipelineOptions} object with default values for each of the options fields. An diff --git a/src/main/java/com/microsoft/azure/storage/blob/ReliableDownloadOptions.java b/src/main/java/com/microsoft/azure/storage/blob/ReliableDownloadOptions.java new file mode 100644 index 000000000000..b0c934b40abb --- /dev/null +++ b/src/main/java/com/microsoft/azure/storage/blob/ReliableDownloadOptions.java @@ -0,0 +1,48 @@ +/* + * 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; + +/** + * {@code ReliableDownloadOptions} contains properties which help the {@code Flowable} returned from + * {@link DownloadResponse#body(ReliableDownloadOptions)} determine when to retry. + */ +public final class ReliableDownloadOptions { + + /* + We use "retry" here because by the time the user passes this type, the initial request, or try, has already been + issued and returned. This is in contrast to the retry policy options, which includes the initial try in its count, + thus the difference in verbiage. + */ + private int maxRetryRequests = 0; + + /** + * Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a + * response body. + */ + public int maxRetryRequests() { + return maxRetryRequests; + } + + /** + * Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a + * response body. + */ + public ReliableDownloadOptions withMaxRetryRequests(int maxRetryRequests) { + Utility.assertInBounds("options.maxRetryRequests", maxRetryRequests, 0, Integer.MAX_VALUE); + this.maxRetryRequests = maxRetryRequests; + return this; + } +} diff --git a/src/main/java/com/microsoft/azure/storage/blob/RequestRetryFactory.java b/src/main/java/com/microsoft/azure/storage/blob/RequestRetryFactory.java index dc950d330eaa..0b1fb02009b3 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/RequestRetryFactory.java +++ b/src/main/java/com/microsoft/azure/storage/blob/RequestRetryFactory.java @@ -14,7 +14,6 @@ */ package com.microsoft.azure.storage.blob; -import com.microsoft.azure.storage.blob.models.StorageErrorException; import com.microsoft.rest.v2.http.*; import com.microsoft.rest.v2.policy.RequestPolicy; import com.microsoft.rest.v2.policy.RequestPolicyFactory; @@ -72,7 +71,7 @@ private RequestRetryPolicy(RequestPolicy nextPolicy, RequestRetryOptions request public Single sendAsync(HttpRequest httpRequest) { boolean considerSecondary = (httpRequest.httpMethod().equals(HttpMethod.GET) || httpRequest.httpMethod().equals(HttpMethod.HEAD)) - && (this.requestRetryOptions.getSecondaryHost() != null); + && (this.requestRetryOptions.secondaryHost() != null); return this.attemptAsync(httpRequest, 1, considerSecondary, 1); } @@ -138,7 +137,7 @@ stream, the buffers that were emitted will have already been consumed (their pos httpRequest.url(), bufferedHeaders, bufferedBody, httpRequest.responseDecoder()); if (!tryingPrimary) { UrlBuilder builder = UrlBuilder.parse(requestCopy.url()); - builder.withHost(this.requestRetryOptions.getSecondaryHost()); + builder.withHost(this.requestRetryOptions.secondaryHost()); try { requestCopy.withUrl(builder.toURL()); } catch (MalformedURLException e) { @@ -153,7 +152,7 @@ stream, the buffers that were emitted will have already been consumed (their pos until after the retry backoff delay, so we call delaySubscription. */ return this.nextPolicy.sendAsync(requestCopy) - .timeout(this.requestRetryOptions.getTryTimeout(), TimeUnit.SECONDS) + .timeout(this.requestRetryOptions.tryTimeout(), TimeUnit.SECONDS) .delaySubscription(delayMs, TimeUnit.MILLISECONDS) .flatMap(response -> { boolean newConsiderSecondary = considerSecondary; @@ -174,7 +173,7 @@ If attempt was against the secondary & it returned a StatusNotFound (404), then action = "NoRetry: Successful HTTP request"; } logf("Action=%s\n", action); - if (action.charAt(0) == 'R' && attempt < requestRetryOptions.getMaxTries()) { + if (action.charAt(0) == 'R' && attempt < requestRetryOptions.maxTries()) { /* We increment primaryTry if we are about to try the primary again (which is when we consider the secondary and tried the secondary this time (tryingPrimary==false) or @@ -189,19 +188,27 @@ we do not consider the secondary at all (considerSecondary==false)). This will return Single.just(response); }) .onErrorResumeNext(throwable -> { + /* + It is likely that many users will not realize that their Flowable must be replayable and + get an error upon retries when the provided data length does not match the length of the exact + data. We cannot enforce the desired Flowable behavior, so we provide a hint when this is likely + the root cause. + */ + if (throwable instanceof UnexpectedLengthException && attempt > 1) { + return Single.error(new IllegalStateException("The request failed because the " + + "size of the contents of the provided Flowable did not match the provided " + + "data size upon attempting to retry. This is likely caused by the Flowable " + + "not being replayable. To support retries, all Flowables must produce the " + + "same data for each subscriber. Please ensure this behavior.", throwable)); + } String action; /* - ChannelException: A RuntimeException which is thrown when an I/O operation fails. - ClosedChannelException: Thrown when an attempt is made to invoke or complete an I/O operation - upon channel that is closed. - SocketException: Thrown to indicate that there is an error creating or accessing a Socket. - SocketTimeoutException: Signals that a timeout has occurred on a socket read or accept. + IOException is a catch-all for IO related errors. Technically it includes many types which may + not be network exceptions, but we should not hit those unless there is a bug in our logic. In + either case, it is better to optimistically retry instead of failing too soon. A Timeout Exception is a client-side timeout coming from Rx. */ - if (throwable instanceof ChannelException || - throwable instanceof ClosedChannelException || - throwable instanceof SocketException || - throwable instanceof SocketTimeoutException) { + if (throwable instanceof IOException) { action = "Retry: Network error"; } else if (throwable instanceof TimeoutException) { action = "Retry: Client timeout"; @@ -210,7 +217,7 @@ we do not consider the secondary at all (considerSecondary==false)). This will } logf("Action=%s\n", action); - if (action.charAt(0) == 'R' && attempt < requestRetryOptions.getMaxTries()) { + if (action.charAt(0) == 'R' && attempt < requestRetryOptions.maxTries()) { /* We increment primaryTry if we are about to try the primary again (which is when we consider the secondary and tried the secondary this time (tryingPrimary==false) or diff --git a/src/main/java/com/microsoft/azure/storage/blob/RequestRetryOptions.java b/src/main/java/com/microsoft/azure/storage/blob/RequestRetryOptions.java index f6e42e955549..f1c24f738726 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/RequestRetryOptions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/RequestRetryOptions.java @@ -126,23 +126,23 @@ public RequestRetryOptions(RetryPolicyType retryPolicyType, Integer maxTries, In this.secondaryHost = secondaryHost; } - int getMaxTries() { + int maxTries() { return this.maxTries; } - int getTryTimeout() { + int tryTimeout() { return this.tryTimeout; } - String getSecondaryHost() { + String secondaryHost() { return this.secondaryHost; } - long getRetryDelayInMs() { + long retryDelayInMs() { return retryDelayInMs; } - long getMaxRetryDelayInMs() { + long maxRetryDelayInMs() { return maxRetryDelayInMs; } diff --git a/src/main/java/com/microsoft/azure/storage/blob/RetryReader.java b/src/main/java/com/microsoft/azure/storage/blob/RetryReader.java deleted file mode 100644 index 3f2c1681ca11..000000000000 --- a/src/main/java/com/microsoft/azure/storage/blob/RetryReader.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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.rest.v2.RestResponse; -import com.microsoft.rest.v2.http.HttpPipeline; -import io.netty.channel.ChannelException; -import io.reactivex.Flowable; -import io.reactivex.Single; -import org.reactivestreams.Subscriber; - -import java.io.IOException; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.nio.ByteBuffer; - -import java.nio.channels.ClosedChannelException; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; - -/** - * {@code RetryReader} is used to wrap a download request and automatically retry failed reads as appropriate. If the - * download is interrupted, the RetryReader will make a request to resume the download from where it left off, allowing - * the user to consume the data as one continuous stream, for any interruptions are hidden. The retry behavior is - * defined by the passed options, and the download will resume according to the provided getter function. - *

- * This type is closely integrated into the {@link BlobURL#download(BlobRange, BlobAccessConditions, boolean)} API. The - * {@link DownloadResponse} emitted by the returned Single if the call to - * {@link DownloadResponse#body(RetryReaderOptions)} is called by passing non null options. - *

- * Note that the retries performed as a part of this reader are composed with those of any retries in an {@link - * HttpPipeline} used in conjunction with this reader. That is, if the reader issues a request to resume a download, - * an underlying pipeline may issue several retries as a part of that request. Furthermore, this reader only retries on - * network errors; timeouts and unexpected status codes are not retried. Therefore, the behavior of this reader is - * entirely independent of and in no way coupled to an {@link HttpPipeline}'s retry mechanism. - */ -public final class RetryReader extends Flowable { - private Single>> response; - - private HTTPGetterInfo info; - - private RetryReaderOptions options; - - private final Function>>> getter; - - public RetryReader(Single>> initialResponse, HTTPGetterInfo info, - RetryReaderOptions options, - Function>>> getter) { - Utility.assertNotNull("getter", getter); - info = info == null ? new HTTPGetterInfo() : info; - if (info.count != null) { - Utility.assertInBounds("info.count", info.count, 0, Integer.MAX_VALUE); - } - options = options == null ? new RetryReaderOptions() : options; - Utility.assertInBounds("options.maxRetryRequests", options.maxRetryRequests, 0, Integer.MAX_VALUE); - - this.response = initialResponse; - this.info = info; - this.options = options; - this.getter = getter; - } - - @Override - protected void subscribeActual(Subscriber s) { - /* - We we were not given a response stream to start with. Get one. We only care about retries on the download - stream, so we do not count this call to get an initial response in our retry count. If the getter itself - fails, we have no way of continuing and so report an error. - */ - if (this.response == null) { - try { - this.response = getter.apply(this.info); - } catch (Throwable throwable) { - s.onError(throwable); - return; - } - } - - Flowable stream = readActual(s, this.response, 0); - - stream.subscribe(); - } - - private Flowable readActual(Subscriber s, - Single>> response, int retryCount) { - return response.flatMapPublisher(RestResponse::body) - /* - Update how much data we have received in case we need to retry and propagate to the user the data we - have received. - */ - .doOnNext(buffer -> { - this.info.offset += buffer.remaining(); - if (info.count != null) { - this.info.count -= buffer.remaining(); - } - s.onNext(buffer); - }) - /* - Each attempt tries to read all of the remaining data. If we make it to the end of the body of a given - request, this download is complete, and we are done. - */ - .doOnComplete(s::onComplete) - /* - Note that this will capture errors from mapping the response to the body, which involves making a - GET request, and errors from trying to read the body. We only care about errors from the body. - */ - .onErrorResumeNext(throwable -> { - // If all the retries are exhausted, report it to the user and error out. - if (retryCount > options.maxRetryRequests) { - s.onError(throwable); - return Flowable.empty(); - } - /* - ChannelException: A RuntimeException which is thrown when an I/O operation fails. - ClosedChannelException: Thrown when an attempt is made to invoke or complete an I/O operation - upon channel that is closed. - SocketException: Thrown to indicate that there is an error creating or accessing a Socket. - SocketTimeoutException: Signals that a timeout has occurred on a socket read or accept. - A Timeout Exception is a client-side timeout coming from Rx. - */ - else if (throwable instanceof ChannelException || - throwable instanceof ClosedChannelException || - throwable instanceof SocketException || - throwable instanceof SocketTimeoutException || - throwable instanceof TimeoutException) { - // Get a new response to try reading from. - Single>> newResponse; - try { - newResponse = getter.apply(info); - } catch (Throwable t) { - s.onError(t); - return Flowable.empty(); - } - - // Continue with the same process again and increment the retryCount. - return readActual(s, newResponse, retryCount + 1); - } else { - s.onError(throwable); - return Flowable.empty(); - } - }); - } - - /** - * HTTPGetterInfo is a passed to the getter function of a RetryReader to specify parameters needed for the GET - * request. - */ - public static class HTTPGetterInfo { - /** - * The start offset that should be used when creating the HTTP GET request's Range header. Defaults to 0. - */ - public long offset = 0; - - /** - * The count of bytes that should be used to calculate the end offset when creating the HTTP GET request's Range - * header. {@code} null is the default and indicates that the entire rest of the blob should be retrieved. - */ - public Long count = null; - - /** - * The resource's etag that should be used when creating the HTTP GET request's If-Match header. Note that the - * Etag is returned with any operation that modifies the resource and by a call to {@link - * BlobURL#getProperties(BlobAccessConditions)}. Defaults to null. - */ - public ETag eTag = null; - } -} diff --git a/src/main/java/com/microsoft/azure/storage/blob/RetryReaderOptions.java b/src/main/java/com/microsoft/azure/storage/blob/RetryReaderOptions.java deleted file mode 100644 index fdda2ed09c30..000000000000 --- a/src/main/java/com/microsoft/azure/storage/blob/RetryReaderOptions.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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; - -/** - * {@code RetryReaderOptions} contains properties which help a {@link RetryReader} determine when to retry. - */ -public final class RetryReaderOptions { - /** - * Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a - * {@link RetryReader}. Note that if no initial response is provided, the {@code RetryReader} will call the getter - * to obtain an initial response to read from; this initial response does not count as a retry. A value of {@code 0} - * is the default and means that no additional HTTP requests will be made once the initial request has been made or - * provided. - */ - public int maxRetryRequests = 0; -} diff --git a/src/main/java/com/microsoft/azure/storage/blob/SASQueryParameters.java b/src/main/java/com/microsoft/azure/storage/blob/SASQueryParameters.java index 8827fab293d8..09685811669c 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/SASQueryParameters.java +++ b/src/main/java/com/microsoft/azure/storage/blob/SASQueryParameters.java @@ -67,7 +67,7 @@ public final class SASQueryParameters { * @return * The storage version */ - public String getVersion() { + public String version() { return version; } @@ -76,7 +76,7 @@ public String getVersion() { * The storage services being accessed (only for Account SAS). Please refer to {@link AccountSASService} for * more details. */ - public String getServices() { + public String services() { return services; } @@ -85,7 +85,7 @@ public String getServices() { * The storage resource types being accessed (only for Account SAS). Please refer to * {@link AccountSASResourceType} for more details. */ - public String getResourceTypes() { + public String resourceTypes() { return resourceTypes; } @@ -93,7 +93,7 @@ public String getResourceTypes() { * @return * The allowed HTTP protocol(s) or {@code null}. Please refer to {@link SASProtocol} for more details. */ - public SASProtocol getProtocol() { + public SASProtocol protocol() { return protocol; } @@ -101,7 +101,7 @@ public SASProtocol getProtocol() { * @return * The start time for this SAS token or {@code null}. */ - public OffsetDateTime getStartTime() { + public OffsetDateTime startTime() { return startTime; } @@ -109,7 +109,7 @@ public OffsetDateTime getStartTime() { * @return * The expiry time for this SAS token. */ - public OffsetDateTime getExpiryTime() { + public OffsetDateTime expiryTime() { return expiryTime; } @@ -117,7 +117,7 @@ public OffsetDateTime getExpiryTime() { * @return * {@link IPRange} */ - public IPRange getIpRange() { + public IPRange ipRange() { return ipRange; } @@ -127,7 +127,7 @@ public IPRange getIpRange() { * here * for more information. */ - public String getIdentifier() { + public String identifier() { return identifier; } @@ -135,7 +135,7 @@ public String getIdentifier() { * @return * The storage container or blob (only for {@link ServiceSASSignatureValues}). */ - public String getResource() { + public String resource() { return resource; } @@ -144,7 +144,7 @@ public String getResource() { * Please refer to {@link AccountSASPermission}, {@link BlobSASPermission}, or {@link ContainerSASPermission} * for more details. */ - public String getPermissions() { + public String permissions() { return permissions; } @@ -152,7 +152,7 @@ public String getPermissions() { * @return * The signature for the SAS token. */ - public String getSignature() { + public String signature() { return signature; } @@ -160,7 +160,7 @@ public String getSignature() { * @return * The Cache-Control header value when a client accesses the resource with this sas token. */ - public String getCacheControl() { + public String cacheControl() { return cacheControl; } @@ -168,7 +168,7 @@ public String getCacheControl() { * @return * The Content-Disposition header value when a client accesses the resource with this sas token. */ - public String getContentDisposition() { + public String contentDisposition() { return contentDisposition; } @@ -176,7 +176,7 @@ public String getContentDisposition() { * @return * The Content-Encoding header value when a client accesses the resource with this sas token. */ - public String getContentEncoding() { + public String contentEncoding() { return contentEncoding; } @@ -184,7 +184,7 @@ public String getContentEncoding() { * @return * The Content-Language header value when a client accesses the resource with this sas token. */ - public String getContentLanguage() { + public String contentLanguage() { return contentLanguage; } @@ -192,7 +192,7 @@ public String getContentLanguage() { * @return * The Content-Type header value when a client accesses the resource with this sas token. */ - public String getContentType() { + public String contentType() { return contentType; } diff --git a/src/main/java/com/microsoft/azure/storage/blob/ServiceSASSignatureValues.java b/src/main/java/com/microsoft/azure/storage/blob/ServiceSASSignatureValues.java index 6bfc5d50f91a..c2af84cc08fa 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ServiceSASSignatureValues.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ServiceSASSignatureValues.java @@ -37,80 +37,251 @@ */ public final class ServiceSASSignatureValues { + private String version = Constants.HeaderConstants.TARGET_STORAGE_VERSION; + + private SASProtocol protocol; + + private OffsetDateTime startTime; + + private OffsetDateTime expiryTime; + + private String permissions; + + private IPRange ipRange; + + private String containerName; + + private String blobName; + + private String identifier; + + private String cacheControl; + + private String contentDisposition; + + private String contentEncoding; + + private String contentLanguage; + + private String contentType; + + /** + * The version of the service this SAS will target. If not specified, it will default to the version targeted by the + * library. + */ + public String version() { + return version; + } + /** * The version of the service this SAS will target. If not specified, it will default to the version targeted by the * library. */ - public String version = Constants.HeaderConstants.TARGET_STORAGE_VERSION; + public ServiceSASSignatureValues withVersion(String version) { + this.version = version; + return this; + } + + /** + * {@link SASProtocol} + */ + public SASProtocol protocol() { + return protocol; + } /** * {@link SASProtocol} */ - public SASProtocol protocol; + public ServiceSASSignatureValues withProtocol(SASProtocol protocol) { + this.protocol = protocol; + return this; + } /** * When the SAS will take effect. */ - public OffsetDateTime startTime; + public OffsetDateTime startTime() { + return startTime; + } + + /** + * When the SAS will take effect. + */ + public ServiceSASSignatureValues withStartTime(OffsetDateTime startTime) { + this.startTime = startTime; + return this; + } /** * The time after which the SAS will no longer work. */ - public OffsetDateTime expiryTime; + public OffsetDateTime expiryTime() { + return expiryTime; + } + + /** + * The time after which the SAS will no longer work. + */ + public ServiceSASSignatureValues withExpiryTime(OffsetDateTime expiryTime) { + this.expiryTime = expiryTime; + return this; + } + + /** + * Please refer to either {@link ContainerSASPermission} or {@link BlobSASPermission} depending on the resource + * being accessed for help constructing the permissions string. + */ + public String permissions() { + return permissions; + } /** * Please refer to either {@link ContainerSASPermission} or {@link BlobSASPermission} depending on the resource * being accessed for help constructing the permissions string. */ - public String permissions; + public ServiceSASSignatureValues withPermissions(String permissions) { + this.permissions = permissions; + return this; + } /** * {@link IPRange} */ - public IPRange ipRange; + public IPRange ipRange() { + return ipRange; + } + + /** + * {@link IPRange} + */ + public ServiceSASSignatureValues withIpRange(IPRange ipRange) { + this.ipRange = ipRange; + return this; + } /** * The name of the container the SAS user may access. */ - public String containerName; + public String containerName() { + return containerName; + } /** * The name of the container the SAS user may access. */ - public String blobName; + public ServiceSASSignatureValues withContainerName(String containerName) { + this.containerName = containerName; + return this; + } + + /** + * The name of the container the SAS user may access. + */ + public String blobName() { + return blobName; + } + + /** + * The name of the container the SAS user may access. + */ + public ServiceSASSignatureValues withBlobName(String blobName) { + this.blobName = blobName; + return this; + } + + /** + * The name of the access policy on the container this SAS references if any. Please see + * here + * for more information. + */ + public String identifier() { + return identifier; + } /** * The name of the access policy on the container this SAS references if any. Please see * here * for more information. */ - public String identifier; + public ServiceSASSignatureValues withIdentifier(String identifier) { + this.identifier = identifier; + return this; + } /** * The cache-control header for the SAS. */ - public String cacheControl; + public String cacheControl() { + return cacheControl; + } + + /** + * The cache-control header for the SAS. + */ + public ServiceSASSignatureValues withCacheControl(String cacheControl) { + this.cacheControl = cacheControl; + return this; + } /** * The content-disposition header for the SAS. */ - public String contentDisposition; + public String contentDisposition() { + return contentDisposition; + } + + /** + * The content-disposition header for the SAS. + */ + public ServiceSASSignatureValues withContentDisposition(String contentDisposition) { + this.contentDisposition = contentDisposition; + return this; + } /** * The content-encoding header for the SAS. - * */ - public String contentEncoding; + public String contentEncoding() { + return contentEncoding; + } + + /** + * The content-encoding header for the SAS. + */ + public ServiceSASSignatureValues withContentEncoding(String contentEncoding) { + this.contentEncoding = contentEncoding; + return this; + } /** * The content-language header for the SAS. */ - public String contentLanguage; + public String contentLanguage() { + return contentLanguage; + } + + /** + * The content-language header for the SAS. + */ + public ServiceSASSignatureValues withContentLanguage(String contentLanguage) { + this.contentLanguage = contentLanguage; + return this; + } /** * The content-type header for the SAS. */ - public String contentType; + public String contentType() { + return contentType; + } + + /** + * The content-type header for the SAS. + */ + public ServiceSASSignatureValues withContentType(String contentType) { + this.contentType = contentType; + return this; + } /** * Creates an object with empty values for all fields. diff --git a/src/main/java/com/microsoft/azure/storage/blob/ServiceURL.java b/src/main/java/com/microsoft/azure/storage/blob/ServiceURL.java index 699dbed69fe2..04476732409d 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/ServiceURL.java +++ b/src/main/java/com/microsoft/azure/storage/blob/ServiceURL.java @@ -15,6 +15,7 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.*; +import com.microsoft.rest.v2.Context; import com.microsoft.rest.v2.http.HttpPipeline; import io.reactivex.Single; @@ -96,15 +97,23 @@ public ServiceURL withPipeline(HttpPipeline pipeline) { * ListContainersSegmentResponse.body().nextMarker(). Set to null to list the first segment. * @param options * A {@link ListContainersOptions} which specifies what data should be returned by the service. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single listContainersSegment( - String marker, ListContainersOptions options) { + public Single listContainersSegment(String marker, + ListContainersOptions options, Context context) { options = options == null ? ListContainersOptions.DEFAULT : options; + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle( - this.storageClient.generatedServices().listContainersSegmentWithRestResponseAsync(options.getPrefix(), - marker, options.getMaxResults(), options.getDetails().toIncludeType(), null, null)); + this.storageClient.generatedServices().listContainersSegmentWithRestResponseAsync(context, + options.prefix(), marker, options.maxResults(), options.details().toIncludeType(), null, null)); } /** @@ -118,10 +127,18 @@ public Single listContainersSegment( * * @return * Emits the successful response. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. */ - public Single getProperties() { + public Single getProperties(Context context) { + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle( - this.storageClient.generatedServices().getPropertiesWithRestResponseAsync(null, null)); + this.storageClient.generatedServices().getPropertiesWithRestResponseAsync(context, null, null)); } /** @@ -137,12 +154,20 @@ public Single getProperties() { * * @param properties * Configures the service. + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single setProperties(StorageServiceProperties properties) { + public Single setProperties(StorageServiceProperties properties, Context context) { + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle( - this.storageClient.generatedServices().setPropertiesWithRestResponseAsync(properties, null, + this.storageClient.generatedServices().setPropertiesWithRestResponseAsync(context, properties, null, null)); } @@ -157,12 +182,20 @@ public Single setProperties(StorageServiceProperti * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=service_stats "Sample code for ServiceURL.getStats")] \n * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getStatistics() { + public Single getStatistics(Context context) { + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle( - this.storageClient.generatedServices().getStatisticsWithRestResponseAsync(null, null)); + this.storageClient.generatedServices().getStatisticsWithRestResponseAsync(context, null, null)); } /** @@ -174,11 +207,19 @@ public Single getStatistics() { * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=account_info "Sample code for ServiceURL.getAccountInfo")] \n * For more samples, please see the [Samples file] (https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/test/java/com/microsoft/azure/storage/Samples.java) * + * @param context + * {@code Context} offers a means of passing arbitrary data (key/value pairs) to an + * {@link com.microsoft.rest.v2.http.HttpPipeline}'s policy objects. Most applications do not need to pass + * arbitrary data to the pipeline and can pass {@code Context.NONE} or {@code null}. Each context object is + * immutable. The {@code withContext} with data method creates a new {@code Context} object that refers to its + * parent, forming a linked list. * @return * Emits the successful response. */ - public Single getAccountInfo() { + public Single getAccountInfo(Context context) { + context = context == null ? Context.NONE : context; + return addErrorWrappingToSingle( - this.storageClient.generatedServices().getAccountInfoWithRestResponseAsync()); + this.storageClient.generatedServices().getAccountInfoWithRestResponseAsync(context)); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/StorageURL.java b/src/main/java/com/microsoft/azure/storage/blob/StorageURL.java index 27704356e365..d3a48e838dbe 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/StorageURL.java +++ b/src/main/java/com/microsoft/azure/storage/blob/StorageURL.java @@ -121,17 +121,17 @@ public static HttpPipeline createPipeline(ICredentials credentials, PipelineOpti // Closest to API goes first, closest to wire goes last. ArrayList factories = new ArrayList<>(); - factories.add(new TelemetryFactory(pipelineOptions.telemetryOptions)); + factories.add(new TelemetryFactory(pipelineOptions.telemetryOptions())); factories.add(new RequestIDFactory()); - factories.add(new RequestRetryFactory(pipelineOptions.requestRetryOptions)); + factories.add(new RequestRetryFactory(pipelineOptions.requestRetryOptions())); if (!(credentials instanceof AnonymousCredentials)) { factories.add(credentials); } factories.add(new DecodingPolicyFactory()); - factories.add(new LoggingFactory(pipelineOptions.loggingOptions)); + factories.add(new LoggingFactory(pipelineOptions.loggingOptions())); - return HttpPipeline.build(new HttpPipelineOptions().withHttpClient(pipelineOptions.client) - .withLogger(pipelineOptions.logger), + return HttpPipeline.build(new HttpPipelineOptions().withHttpClient(pipelineOptions.client()) + .withLogger(pipelineOptions.logger()), factories.toArray(new RequestPolicyFactory[factories.size()])); } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/TelemetryFactory.java b/src/main/java/com/microsoft/azure/storage/blob/TelemetryFactory.java index 6be728f58ba2..5d2855e91cc5 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/TelemetryFactory.java +++ b/src/main/java/com/microsoft/azure/storage/blob/TelemetryFactory.java @@ -43,8 +43,8 @@ public final class TelemetryFactory implements RequestPolicyFactory { */ public TelemetryFactory(TelemetryOptions telemetryOptions) { telemetryOptions = telemetryOptions == null ? TelemetryOptions.DEFAULT : telemetryOptions; - String userAgentPrefix = telemetryOptions.getUserAgentPrefix() == null ? - Constants.EMPTY_STRING : telemetryOptions.getUserAgentPrefix(); + String userAgentPrefix = telemetryOptions.userAgentPrefix() == null ? + Constants.EMPTY_STRING : telemetryOptions.userAgentPrefix(); this.userAgent = userAgentPrefix + ' ' + Constants.HeaderConstants.USER_AGENT_PREFIX + '/' + Constants.HeaderConstants.USER_AGENT_VERSION + String.format(Locale.ROOT, " (JavaJRE %s; %s %s)", diff --git a/src/main/java/com/microsoft/azure/storage/blob/TelemetryOptions.java b/src/main/java/com/microsoft/azure/storage/blob/TelemetryOptions.java index da45cf384762..e436f5d7a194 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/TelemetryOptions.java +++ b/src/main/java/com/microsoft/azure/storage/blob/TelemetryOptions.java @@ -36,7 +36,7 @@ public TelemetryOptions(String userAgentPrefix) { * @return * The user agent prefix. */ - public String getUserAgentPrefix() { + public String userAgentPrefix() { return this.userAgentPrefix; } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/TransferManager.java b/src/main/java/com/microsoft/azure/storage/blob/TransferManager.java index 5a002069e0ed..00679a86bbea 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/TransferManager.java +++ b/src/main/java/com/microsoft/azure/storage/blob/TransferManager.java @@ -16,6 +16,7 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.BlobDownloadHeaders; +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions; import com.microsoft.rest.v2.util.FlowableUtil; import io.reactivex.Flowable; import io.reactivex.Observable; @@ -38,7 +39,7 @@ * operations. Further, we will make our own assumptions and optimizations for common cases that may not be ideal for * rarer cases. */ -public class TransferManager { +public final class TransferManager { /** * The default size of a download chunk for download large blobs. @@ -63,27 +64,27 @@ public class TransferManager { * between 1 and {@link BlockBlobURL#MAX_STAGE_BLOCK_BYTES}. Note as well that * {@code fileLength/blockLength} must be less than or equal to {@link BlockBlobURL#MAX_BLOCKS}. * @param options - * {@link UploadToBlockBlobOptions} + * {@link TransferManagerUploadToBlockBlobOptions} * @return Emits the successful response. */ public static Single uploadFileToBlockBlob( final AsynchronousFileChannel file, final BlockBlobURL blockBlobURL, final int blockLength, - final UploadToBlockBlobOptions options) throws IOException { + final TransferManagerUploadToBlockBlobOptions options) throws IOException { Utility.assertNotNull("file", file); Utility.assertNotNull("blockBlobURL", blockBlobURL); Utility.assertInBounds("blockLength", blockLength, 1, BlockBlobURL.MAX_STAGE_BLOCK_BYTES); - UploadToBlockBlobOptions optionsReal = options == null ? UploadToBlockBlobOptions.DEFAULT : options; + TransferManagerUploadToBlockBlobOptions optionsReal = options == null ? TransferManagerUploadToBlockBlobOptions.DEFAULT : options; // If the size of the file can fit in a single upload, do it this way. if (file.size() < BlockBlobURL.MAX_UPLOAD_BLOB_BYTES) { - if (optionsReal.progressReceiver != null) { + if (optionsReal.progressReceiver() != null) { // TODO: Wrap in a progress stream once progress is written. } // Transform the specific RestResponse into a CommonRestResponse. - return blockBlobURL.upload(FlowableUtil.readFile(file), file.size(), optionsReal.httpHeaders, - optionsReal.metadata, optionsReal.accessConditions) + return blockBlobURL.upload(FlowableUtil.readFile(file), file.size(), optionsReal.httpHeaders(), + optionsReal.metadata(), optionsReal.accessConditions(), null) .map(CommonRestResponse::createFromPutBlobResponse); } @@ -115,7 +116,7 @@ public static Single uploadFileToBlockBlob( concatMapEager. */ return blockBlobURL.stageBlock(blockId, data, - count, optionsReal.accessConditions.getLeaseAccessConditions()) + count, optionsReal.accessConditions().leaseAccessConditions(), null) .map(x -> blockId).toObservable(); /* @@ -126,7 +127,7 @@ public static Single uploadFileToBlockBlob( stageBlock is finished. Prefetch is a hint that each of the Observables emitted by the source will emit only one value, which is true here because we have converted from a Single. */ - }, optionsReal.parallelism, 1) + }, optionsReal.parallelism(), 1) /* collectInto will gather each of the emitted blockIds into a list. Because we used concatMap, the Ids will be emitted according to their block number, which means the list generated here will be @@ -139,8 +140,9 @@ public static Single uploadFileToBlockBlob( can "map" it into a call to commitBlockList. */ .flatMap(ids -> - blockBlobURL.commitBlockList(ids, optionsReal.httpHeaders, optionsReal.metadata, - optionsReal.accessConditions)) + blockBlobURL.commitBlockList(ids, optionsReal.httpHeaders(), optionsReal.metadata(), + optionsReal.accessConditions(), null)) + // Finally, we must turn the specific response type into a CommonRestResponse by mapping. .map(CommonRestResponse::createFromPutBlockListResponse); } @@ -169,13 +171,13 @@ private static int calculateNumBlocks(long dataSize, long blockLength) { * @param range * {@link BlobRange} * @param options - * {@link DownloadFromBlobOptions} + * {@link TransferManagerDownloadFromBlobOptions} * @return A {@code Completable} that will signal when the download is complete. */ public static Single downloadBlobToFile(AsynchronousFileChannel file, BlobURL blobURL, - BlobRange range, DownloadFromBlobOptions options) { + BlobRange range, TransferManagerDownloadFromBlobOptions options) { BlobRange r = range == null ? BlobRange.DEFAULT : range; - DownloadFromBlobOptions o = options == null ? DownloadFromBlobOptions.DEFAULT : options; + TransferManagerDownloadFromBlobOptions o = options == null ? TransferManagerDownloadFromBlobOptions.DEFAULT : options; Utility.assertNotNull("blobURL", blobURL); Utility.assertNotNull("file", file); @@ -186,7 +188,7 @@ public static Single downloadBlobToFile(AsynchronousFileCha Long dataSize = setupPair.getKey(); BlobAccessConditions realConditions = setupPair.getValue(); - int numChunks = calculateNumBlocks(dataSize, o.chunkSize); + int numChunks = calculateNumBlocks(dataSize, o.chunkSize()); // In case it is an empty blob, this ensures we still actually perform a download operation. numChunks = numChunks == 0 ? 1 : numChunks; @@ -194,25 +196,26 @@ public static Single downloadBlobToFile(AsynchronousFileCha return Observable.range(0, numChunks) .flatMap(i -> { // Calculate whether we need a full chunk or something smaller because we are at the end. - long chunkSizeActual = Math.min(o.chunkSize, - dataSize - (i * o.chunkSize)); - BlobRange chunkRange = new BlobRange(r.getOffset() + (i * o.chunkSize), - chunkSizeActual); + long chunkSizeActual = Math.min(o.chunkSize(), + dataSize - (i * o.chunkSize())); + BlobRange chunkRange = new BlobRange().withOffset(r.offset() + (i * o.chunkSize())) + .withCount(chunkSizeActual); + // Make the download call. - return blobURL.download(chunkRange, realConditions, false) + return blobURL.download(chunkRange, realConditions, false, null) // Extract the body. .flatMapObservable(response -> // Write to the file. - FlowableUtil.writeFile(response.body(o.retryReaderOptionsPerBlock), file, - i * o.chunkSize) + FlowableUtil.writeFile(response.body(o.reliableDownloadOptionsPerBlock()), file, + i * o.chunkSize()) /* Satisfy the return type. Observable required for flatmap to accept maxConcurrency. We want to eventually give the user back the headers. */ .andThen(Single.just(response.headers())) .toObservable()); - }, o.parallelism) + }, o.parallelism()) // All the headers will be the same, so we just pick the last one. .lastOrError(); }); @@ -221,28 +224,29 @@ public static Single downloadBlobToFile(AsynchronousFileCha private static Single> getSetupSingle(BlobURL blobURL, BlobRange r, - DownloadFromBlobOptions o) { + TransferManagerDownloadFromBlobOptions o) { /* Construct a Single which will emit the total count of bytes to be downloaded and retrieve an etag to lock on to if one was not specified. We use a single for this because we may have to make a REST call to get the length to calculate the count and we need to maintain asynchronicity. */ - if (r.getCount() == null || o.accessConditions.getHttpAccessConditions().getIfMatch() == ETag.NONE) { - return blobURL.getProperties(o.accessConditions) + if (r.count() == null || o.accessConditions().modifiedAccessConditions().ifMatch() == null) { + return blobURL.getProperties(o.accessConditions(), null) .map(response -> { BlobAccessConditions newConditions; - if (o.accessConditions.getHttpAccessConditions().getIfMatch() == ETag.NONE) { - newConditions = new BlobAccessConditions( - new HTTPAccessConditions( - o.accessConditions.getHttpAccessConditions().getIfModifiedSince(), - o.accessConditions.getHttpAccessConditions().getIfUnmodifiedSince(), - new ETag(response.headers().eTag()), - o.accessConditions.getHttpAccessConditions().getIfNoneMatch()), - o.accessConditions.getLeaseAccessConditions(), - o.accessConditions.getAppendBlobAccessConditions(), - o.accessConditions.getPageBlobAccessConditions()); + if (o.accessConditions().modifiedAccessConditions().ifMatch() == null) { + newConditions = new BlobAccessConditions() + .withModifiedAccessConditions(new ModifiedAccessConditions() + .withIfModifiedSince( + o.accessConditions().modifiedAccessConditions().ifModifiedSince()) + .withIfUnmodifiedSince( + o.accessConditions().modifiedAccessConditions().ifUnmodifiedSince()) + .withIfMatch(response.headers().eTag()) + .withIfNoneMatch( + o.accessConditions().modifiedAccessConditions().ifNoneMatch())) + .withLeaseAccessConditions(o.accessConditions().leaseAccessConditions()); } else { - newConditions = o.accessConditions; + newConditions = o.accessConditions(); } long newCount; /* @@ -250,131 +254,16 @@ private static Single> getSetupSingle(BlobURL b remaining data, take the size of the remaining data. This is to prevent the case where the count is much much larger than the size of the blob and we could try to download at an invalid offset. */ - if (r.getCount() == null || r.getCount() > response.headers().contentLength() - r.getOffset()) { - newCount = response.headers().contentLength() - r.getOffset(); + if (r.count() == null || r.count() > response.headers().contentLength() - r.offset()) { + newCount = response.headers().contentLength() - r.offset(); } else { - newCount = r.getCount(); + newCount = r.count(); } return new Pair<>(newCount, newConditions); }); } else { - return Single.just(new Pair<>(r.getCount(), o.accessConditions)); - } - } - - /** - * Configures the parallel upload behavior for methods on the {@code TransferManager}. - */ - public static class UploadToBlockBlobOptions { - - /** - * An object which represents the default parallel upload options. - */ - public static final UploadToBlockBlobOptions DEFAULT = new UploadToBlockBlobOptions(null, - null, null, null, null); - - private final IProgressReceiver progressReceiver; - - private final BlobHTTPHeaders httpHeaders; - - private final Metadata metadata; - - private final BlobAccessConditions accessConditions; - - private final int parallelism; - - /** - * Creates a new object that configures the parallel upload behavior. Null may be passed to accept the default - * behavior. - * - * @param progressReceiver - * An object that implements the {@link IProgressReceiver} interface which will be invoked periodically - * as bytes are sent in a PutBlock call to the BlockBlobURL. May be null if no progress reports are - * desired. - * @param httpHeaders - * {@link BlobHTTPHeaders} - * @param metadata - * {@link Metadata} - * @param accessConditions - * {@link BlobAccessConditions} - * @param parallelism - * A {@code int} that indicates the maximum number of blocks to upload in parallel. Must be greater than - * 0. May be null to accept default behavior. - */ - public UploadToBlockBlobOptions(IProgressReceiver progressReceiver, BlobHTTPHeaders httpHeaders, - Metadata metadata, BlobAccessConditions accessConditions, Integer parallelism) { - if (parallelism == null) { - this.parallelism = Constants.TRANSFER_MANAGER_DEFAULT_PARALLELISM; - } else if (parallelism <= 0) { - throw new IllegalArgumentException("Parallelism must be > 0"); - } else { - this.parallelism = parallelism; - } - - this.progressReceiver = progressReceiver; - this.httpHeaders = httpHeaders; - this.metadata = metadata; - this.accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + return Single.just(new Pair<>(r.count(), o.accessConditions())); } } - /** - * Configures the parallel download behavior for methods on the {@code TransferManager}. - */ - public static final class DownloadFromBlobOptions { - - /** - * The default download options. - */ - public static final DownloadFromBlobOptions DEFAULT = new DownloadFromBlobOptions(null, - null, null, null, null); - - private final long chunkSize; - - private final IProgressReceiver progressReceiver; - private final int parallelism; - private final RetryReaderOptions retryReaderOptionsPerBlock; - // Cannot be final because we may have to set this property in order to lock on the etag. - private BlobAccessConditions accessConditions; - - /** - * Returns an object that configures the parallel download behavior for methods on the {@code TransferManager}. - * - * @param chunkSize - * The size of the chunk into which large download operations will be broken into. Note that if the - * chunkSize is large, fewer but larger requests will be made as each REST request will download a - * single chunk in full. For larger chunk sizes, it may be helpful to configure the - * {@code retryReaderOptions} to allow more retries. - * @param progressReceiver - * {@link IProgressReceiver} - * @param accessConditions - * {@link BlobAccessConditions} - * @param parallelism - * A {@code int} that indicates the maximum number of chunks to download in parallel. Must be greater - * than 0. May be null to accept default behavior. - * @param retryReaderOptions - * {@link RetryReaderOptions} - */ - public DownloadFromBlobOptions(Long chunkSize, IProgressReceiver progressReceiver, - BlobAccessConditions accessConditions, Integer parallelism, RetryReaderOptions retryReaderOptions) { - if (chunkSize != null) { - Utility.assertInBounds("chunkSize", chunkSize, 1, Long.MAX_VALUE); - this.chunkSize = chunkSize; - } else { - this.chunkSize = TransferManager.BLOB_DEFAULT_DOWNLOAD_BLOCK_SIZE; - } - - if (parallelism != null) { - Utility.assertInBounds("parallelism", parallelism, 1, Integer.MAX_VALUE); - this.parallelism = parallelism; - } else { - this.parallelism = Constants.TRANSFER_MANAGER_DEFAULT_PARALLELISM; - } - - this.accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; - this.progressReceiver = progressReceiver; - this.retryReaderOptionsPerBlock = retryReaderOptions == null ? - new RetryReaderOptions() : retryReaderOptions; - } - } } diff --git a/src/main/java/com/microsoft/azure/storage/blob/TransferManagerDownloadFromBlobOptions.java b/src/main/java/com/microsoft/azure/storage/blob/TransferManagerDownloadFromBlobOptions.java new file mode 100644 index 000000000000..b9e1f5e1038e --- /dev/null +++ b/src/main/java/com/microsoft/azure/storage/blob/TransferManagerDownloadFromBlobOptions.java @@ -0,0 +1,96 @@ +/* + * 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; + +/** + * Configures the parallel download behavior for methods on the {@code TransferManager}. + */ +public final class TransferManagerDownloadFromBlobOptions { + + /** + * The default download options. + */ + public static final TransferManagerDownloadFromBlobOptions DEFAULT = + new TransferManagerDownloadFromBlobOptions(null, null, null, null, null); + + private final long chunkSize; + + private final IProgressReceiver progressReceiver; + private final int parallelism; + private final ReliableDownloadOptions reliableDownloadOptionsPerBlock; + // Cannot be final because we may have to set this property in order to lock on the etag. + private BlobAccessConditions accessConditions; + + public long chunkSize() { + return chunkSize; + } + + public IProgressReceiver progressReceiver() { + return progressReceiver; + } + + public int parallelism() { + return parallelism; + } + + public ReliableDownloadOptions reliableDownloadOptionsPerBlock() { + return reliableDownloadOptionsPerBlock; + } + + public BlobAccessConditions accessConditions() { + return accessConditions; + } + + /** + * Returns an object that configures the parallel download behavior for methods on the {@code TransferManager}. + * + * @param chunkSize + * The size of the chunk into which large download operations will be broken into. Note that if the + * chunkSize is large, fewer but larger requests will be made as each REST request will download a + * single chunk in full. For larger chunk sizes, it may be helpful to configure the + * {@code reliableDownloadOptions} to allow more retries. + * @param progressReceiver + * {@link IProgressReceiver} + * @param accessConditions + * {@link BlobAccessConditions} + * @param parallelism + * A {@code int} that indicates the maximum number of chunks to download in parallel. Must be greater + * than 0. May be null to accept default behavior. + * @param reliableDownloadOptions + * {@link ReliableDownloadOptions} + */ + public TransferManagerDownloadFromBlobOptions(Long chunkSize, IProgressReceiver progressReceiver, + BlobAccessConditions accessConditions, Integer parallelism, ReliableDownloadOptions reliableDownloadOptions) { + if (chunkSize != null) { + Utility.assertInBounds("chunkSize", chunkSize, 1, Long.MAX_VALUE); + this.chunkSize = chunkSize; + } else { + this.chunkSize = TransferManager.BLOB_DEFAULT_DOWNLOAD_BLOCK_SIZE; + } + + if (parallelism != null) { + Utility.assertInBounds("parallelism", parallelism, 1, Integer.MAX_VALUE); + this.parallelism = parallelism; + } else { + this.parallelism = Constants.TRANSFER_MANAGER_DEFAULT_PARALLELISM; + } + + this.accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + this.progressReceiver = progressReceiver; + this.reliableDownloadOptionsPerBlock = reliableDownloadOptions == null ? + new ReliableDownloadOptions() : reliableDownloadOptions; + } +} diff --git a/src/main/java/com/microsoft/azure/storage/blob/TransferManagerUploadToBlockBlobOptions.java b/src/main/java/com/microsoft/azure/storage/blob/TransferManagerUploadToBlockBlobOptions.java new file mode 100644 index 000000000000..04a0cccbd931 --- /dev/null +++ b/src/main/java/com/microsoft/azure/storage/blob/TransferManagerUploadToBlockBlobOptions.java @@ -0,0 +1,96 @@ +/* + * 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.blob.models.BlobHTTPHeaders; + +/** + * Configures the parallel upload behavior for methods on the {@code TransferManager}. + */ +public class TransferManagerUploadToBlockBlobOptions { + + /** + * An object which represents the default parallel upload options. + */ + public static final TransferManagerUploadToBlockBlobOptions DEFAULT = new TransferManagerUploadToBlockBlobOptions(null, + null, null, null, null); + + private final IProgressReceiver progressReceiver; + + private final BlobHTTPHeaders httpHeaders; + + private final Metadata metadata; + + private final BlobAccessConditions accessConditions; + + private final int parallelism; + + public IProgressReceiver progressReceiver() { + return progressReceiver; + } + + public BlobHTTPHeaders httpHeaders() { + return httpHeaders; + } + + public Metadata metadata() { + return metadata; + } + + public BlobAccessConditions accessConditions() { + return accessConditions; + } + + public int parallelism() { + return parallelism; + } + + /** + * Creates a new object that configures the parallel upload behavior. Null may be passed to accept the default + * behavior. + * + * @param progressReceiver + * An object that implements the {@link IProgressReceiver} interface which will be invoked periodically + * as bytes are sent in a PutBlock call to the BlockBlobURL. May be null if no progress reports are + * desired. + * @param httpHeaders + * Most often used when creating a blob or setting its properties, this class contains fields for typical HTTP + * properties, which, if specified, will be attached to the target blob. Null may be passed to any API which takes this + * type to indicate that no properties should be set. + * @param metadata + * {@link Metadata} + * @param accessConditions + * {@link BlobAccessConditions} + * @param parallelism + * A {@code int} that indicates the maximum number of blocks to upload in parallel. Must be greater than + * 0. May be null to accept default behavior. + */ + public TransferManagerUploadToBlockBlobOptions(IProgressReceiver progressReceiver, BlobHTTPHeaders httpHeaders, + Metadata metadata, BlobAccessConditions accessConditions, Integer parallelism) { + if (parallelism == null) { + this.parallelism = Constants.TRANSFER_MANAGER_DEFAULT_PARALLELISM; + } else if (parallelism <= 0) { + throw new IllegalArgumentException("Parallelism must be > 0"); + } else { + this.parallelism = parallelism; + } + + this.progressReceiver = progressReceiver; + this.httpHeaders = httpHeaders; + this.metadata = metadata; + this.accessConditions = accessConditions == null ? BlobAccessConditions.NONE : accessConditions; + } +} diff --git a/src/main/java/com/microsoft/azure/storage/blob/URLParser.java b/src/main/java/com/microsoft/azure/storage/blob/URLParser.java index 3e1ad897bead..8c4951fa0309 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/URLParser.java +++ b/src/main/java/com/microsoft/azure/storage/blob/URLParser.java @@ -77,15 +77,14 @@ public static BlobURLParts parse(URL url) throws UnknownHostException { SASQueryParameters sasQueryParameters = new SASQueryParameters(queryParamsMap, true); - BlobURLParts parts = new BlobURLParts(); - parts.scheme = scheme; - parts.host = host; - parts.containerName =containerName; - parts.blobName = blobName; - parts.snapshot = snapshot; - parts.sasQueryParameters = sasQueryParameters; - parts.unparsedParameters = queryParamsMap; - return parts; + return new BlobURLParts() + .withScheme(scheme) + .withHost(host) + .withContainerName(containerName) + .withBlobName(blobName) + .withSnapshot(snapshot) + .withSasQueryParameters(sasQueryParameters) + .withUnparsedParameters(queryParamsMap); } /** diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/AppendPositionAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/models/AppendPositionAccessConditions.java new file mode 100644 index 000000000000..761b7fe5e63a --- /dev/null +++ b/src/main/java/com/microsoft/azure/storage/blob/models/AppendPositionAccessConditions.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package com.microsoft.azure.storage.blob.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +/** + * Additional parameters for appendBlock operation. + */ +@JacksonXmlRootElement(localName = "append-position-access-conditions") +public final class AppendPositionAccessConditions { + /** + * Optional conditional header. The max length in bytes permitted for the + * append blob. If the Append Block operation would cause the blob to + * exceed that limit or if the blob size is already greater than the value + * specified in this header, the request will fail with + * MaxBlobSizeConditionNotMet error (HTTP status code 412 - Precondition + * Failed). + */ + @JsonProperty(value = "MaxSize") + private Long maxSize; + + /** + * Optional conditional header, used only for the Append Block operation. A + * number indicating the byte offset to compare. Append Block will succeed + * only if the append position is equal to this number. If it is not, the + * request will fail with the AppendPositionConditionNotMet error (HTTP + * status code 412 - Precondition Failed). + */ + @JsonProperty(value = "AppendPosition") + private Long appendPosition; + + /** + * Get the maxSize value. + * + * @return the maxSize value. + */ + public Long maxSize() { + return this.maxSize; + } + + /** + * Set the maxSize value. + * + * @param maxSize the maxSize value to set. + * @return the AppendPositionAccessConditions object itself. + */ + public AppendPositionAccessConditions withMaxSize(Long maxSize) { + this.maxSize = maxSize; + return this; + } + + /** + * Get the appendPosition value. + * + * @return the appendPosition value. + */ + public Long appendPosition() { + return this.appendPosition; + } + + /** + * Set the appendPosition value. + * + * @param appendPosition the appendPosition value to set. + * @return the AppendPositionAccessConditions object itself. + */ + public AppendPositionAccessConditions withAppendPosition(Long appendPosition) { + this.appendPosition = appendPosition; + return this; + } +} diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/BlobDownloadHeaders.java b/src/main/java/com/microsoft/azure/storage/blob/models/BlobDownloadHeaders.java index c5f4d516ecdd..9f3c69a29b90 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/models/BlobDownloadHeaders.java +++ b/src/main/java/com/microsoft/azure/storage/blob/models/BlobDownloadHeaders.java @@ -44,7 +44,7 @@ public final class BlobDownloadHeaders { private Long contentLength; /** - * The content type specified for the blob. The default content type is + * The media type of the body of the response. For Download Blob this is * 'application/octet-stream'. */ @JsonProperty(value = "Content-Type") diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/BlobHTTPHeaders.java b/src/main/java/com/microsoft/azure/storage/blob/models/BlobHTTPHeaders.java new file mode 100644 index 000000000000..477dcd80edaf --- /dev/null +++ b/src/main/java/com/microsoft/azure/storage/blob/models/BlobHTTPHeaders.java @@ -0,0 +1,183 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package com.microsoft.azure.storage.blob.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +/** + * Additional parameters for a set of operations. + */ +@JacksonXmlRootElement(localName = "blob-HTTP-headers") +public final class BlobHTTPHeaders { + /** + * Optional. Sets the blob's cache control. If specified, this property is + * stored with the blob and returned with a read request. + */ + @JsonProperty(value = "BlobCacheControl") + private String blobCacheControl; + + /** + * Optional. Sets the blob's content type. If specified, this property is + * stored with the blob and returned with a read request. + */ + @JsonProperty(value = "BlobContentType") + private String blobContentType; + + /** + * Optional. An MD5 hash of the blob content. Note that this hash is not + * validated, as the hashes for the individual blocks were validated when + * each was uploaded. + */ + @JsonProperty(value = "BlobContentMD5") + private byte[] blobContentMD5; + + /** + * Optional. Sets the blob's content encoding. If specified, this property + * is stored with the blob and returned with a read request. + */ + @JsonProperty(value = "BlobContentEncoding") + private String blobContentEncoding; + + /** + * Optional. Set the blob's content language. If specified, this property + * is stored with the blob and returned with a read request. + */ + @JsonProperty(value = "BlobContentLanguage") + private String blobContentLanguage; + + /** + * Optional. Sets the blob's Content-Disposition header. + */ + @JsonProperty(value = "BlobContentDisposition") + private String blobContentDisposition; + + /** + * Get the blobCacheControl value. + * + * @return the blobCacheControl value. + */ + public String blobCacheControl() { + return this.blobCacheControl; + } + + /** + * Set the blobCacheControl value. + * + * @param blobCacheControl the blobCacheControl value to set. + * @return the BlobHTTPHeaders object itself. + */ + public BlobHTTPHeaders withBlobCacheControl(String blobCacheControl) { + this.blobCacheControl = blobCacheControl; + return this; + } + + /** + * Get the blobContentType value. + * + * @return the blobContentType value. + */ + public String blobContentType() { + return this.blobContentType; + } + + /** + * Set the blobContentType value. + * + * @param blobContentType the blobContentType value to set. + * @return the BlobHTTPHeaders object itself. + */ + public BlobHTTPHeaders withBlobContentType(String blobContentType) { + this.blobContentType = blobContentType; + return this; + } + + /** + * Get the blobContentMD5 value. + * + * @return the blobContentMD5 value. + */ + public byte[] blobContentMD5() { + return this.blobContentMD5; + } + + /** + * Set the blobContentMD5 value. + * + * @param blobContentMD5 the blobContentMD5 value to set. + * @return the BlobHTTPHeaders object itself. + */ + public BlobHTTPHeaders withBlobContentMD5(byte[] blobContentMD5) { + this.blobContentMD5 = blobContentMD5; + return this; + } + + /** + * Get the blobContentEncoding value. + * + * @return the blobContentEncoding value. + */ + public String blobContentEncoding() { + return this.blobContentEncoding; + } + + /** + * Set the blobContentEncoding value. + * + * @param blobContentEncoding the blobContentEncoding value to set. + * @return the BlobHTTPHeaders object itself. + */ + public BlobHTTPHeaders withBlobContentEncoding(String blobContentEncoding) { + this.blobContentEncoding = blobContentEncoding; + return this; + } + + /** + * Get the blobContentLanguage value. + * + * @return the blobContentLanguage value. + */ + public String blobContentLanguage() { + return this.blobContentLanguage; + } + + /** + * Set the blobContentLanguage value. + * + * @param blobContentLanguage the blobContentLanguage value to set. + * @return the BlobHTTPHeaders object itself. + */ + public BlobHTTPHeaders withBlobContentLanguage(String blobContentLanguage) { + this.blobContentLanguage = blobContentLanguage; + return this; + } + + /** + * Get the blobContentDisposition value. + * + * @return the blobContentDisposition value. + */ + public String blobContentDisposition() { + return this.blobContentDisposition; + } + + /** + * Set the blobContentDisposition value. + * + * @param blobContentDisposition the blobContentDisposition value to set. + * @return the BlobHTTPHeaders object itself. + */ + public BlobHTTPHeaders withBlobContentDisposition(String blobContentDisposition) { + this.blobContentDisposition = blobContentDisposition; + return this; + } +} diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/BlockBlobGetBlockListHeaders.java b/src/main/java/com/microsoft/azure/storage/blob/models/BlockBlobGetBlockListHeaders.java index 44eeda65e0d8..27358a7a4bbd 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/models/BlockBlobGetBlockListHeaders.java +++ b/src/main/java/com/microsoft/azure/storage/blob/models/BlockBlobGetBlockListHeaders.java @@ -38,8 +38,8 @@ public final class BlockBlobGetBlockListHeaders { private String eTag; /** - * The content type specified for the blob. The default content type is - * 'application/octet-stream'. + * The media type of the body of the response. For Get Block List this is + * 'application/xml'. */ @JsonProperty(value = "Content-Type") private String contentType; diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobFlatSegmentHeaders.java b/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobFlatSegmentHeaders.java index 0f735464db04..42340ff400f9 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobFlatSegmentHeaders.java +++ b/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobFlatSegmentHeaders.java @@ -22,8 +22,8 @@ @JacksonXmlRootElement(localName = "Container-ListBlobFlatSegment-Headers") public final class ContainerListBlobFlatSegmentHeaders { /** - * The content type specified for the blob. The default content type is - * 'application/octet-stream'. + * The media type of the body of the response. For List Blobs this is + * 'application/xml'. */ @JsonProperty(value = "Content-Type") private String contentType; diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobHierarchySegmentHeaders.java b/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobHierarchySegmentHeaders.java index 38b5195a606b..2c5f83d18305 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobHierarchySegmentHeaders.java +++ b/src/main/java/com/microsoft/azure/storage/blob/models/ContainerListBlobHierarchySegmentHeaders.java @@ -22,8 +22,8 @@ @JacksonXmlRootElement(localName = "Container-ListBlobHierarchySegment-Headers") public final class ContainerListBlobHierarchySegmentHeaders { /** - * The content type specified for the blob. The default content type is - * 'application/octet-stream'. + * The media type of the body of the response. For List Blobs this is + * 'application/xml'. */ @JsonProperty(value = "Content-Type") private String contentType; diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/LeaseAccessConditions.java b/src/main/java/com/microsoft/azure/storage/blob/models/LeaseAccessConditions.java new file mode 100644 index 000000000000..aee109b1759c --- /dev/null +++ b/src/main/java/com/microsoft/azure/storage/blob/models/LeaseAccessConditions.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package com.microsoft.azure.storage.blob.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +/** + * Additional parameters for a set of operations. + */ +@JacksonXmlRootElement(localName = "lease-access-conditions") +public final class LeaseAccessConditions { + /** + * If specified, the operation only succeeds if the resource's lease is + * active and matches this ID. + */ + @JsonProperty(value = "LeaseId") + private String leaseId; + + /** + * Get the leaseId value. + * + * @return the leaseId value. + */ + public String leaseId() { + return this.leaseId; + } + + /** + * Set the leaseId value. + * + * @param leaseId the leaseId value to set. + * @return the LeaseAccessConditions object itself. + */ + public LeaseAccessConditions withLeaseId(String leaseId) { + this.leaseId = leaseId; + return this; + } +} diff --git a/src/main/java/com/microsoft/azure/storage/blob/models/ListContainersSegmentResponse.java b/src/main/java/com/microsoft/azure/storage/blob/models/ListContainersSegmentResponse.java index 4bce395b5633..375389d231e6 100644 --- a/src/main/java/com/microsoft/azure/storage/blob/models/ListContainersSegmentResponse.java +++ b/src/main/java/com/microsoft/azure/storage/blob/models/ListContainersSegmentResponse.java @@ -59,7 +59,7 @@ private ContainersWrapper(@JacksonXmlProperty(localName = "Container") List defaultFlowable = Flowable.just(defaultData) + static final Flowable defaultFlowable = Flowable.just(defaultData) - @Shared - int defaultDataSize = defaultData.remaining() + static defaultDataSize = defaultData.remaining() // If debugging is enabled, recordings cannot run as there can only be one proxy at a time. - static final boolean enableDebugging = false + static boolean enableDebugging = false - static final String containerPrefix = "jtc" // java test container + // Prefixes for blobs and containers + static String containerPrefix = "jtc" // java test container - static final String blobPrefix = "javablob" + static String blobPrefix = "javablob" /* The values below are used to create data-driven tests for access conditions. @@ -84,9 +88,9 @@ class APISpec extends Specification { Note that this value is only used to check if we are depending on the received etag. This value will not actually be used. */ - static final ETag receivedEtag = new ETag("received") + static final String receivedEtag = "received" - static final ETag garbageEtag = new ETag("garbage") + static final String garbageEtag = "garbage" /* Note that this value is only used to check if we are depending on the received etag. This value will not actually @@ -96,18 +100,33 @@ class APISpec extends Specification { static final String garbageLeaseID = UUID.randomUUID().toString() + /* + Credentials for various kinds of accounts. + */ static SharedKeyCredentials primaryCreds = getGenericCreds("") static ServiceURL primaryServiceURL = getGenericServiceURL(primaryCreds) static SharedKeyCredentials alternateCreds = getGenericCreds("SECONDARY_") + /* + URLs to various kinds of accounts. + */ static ServiceURL alternateServiceURL = getGenericServiceURL(alternateCreds) static ServiceURL blobStorageServiceURL = getGenericServiceURL(getGenericCreds("BLOB_STORAGE_")) static ServiceURL premiumServiceURL = getGenericServiceURL(getGenericCreds("PREMIUM_")) + /* + Constants for testing that the context parameter is properly passed to the pipeline. + */ + static final String defaultContextKey = "Key" + + static final String defaultContextValue = "Value" + + static final Context defaultContext = new Context(defaultContextKey, defaultContextValue) + static String getTestName(ISpecificationContext ctx) { return ctx.getCurrentFeature().name.replace(' ', '').toLowerCase() } @@ -180,8 +199,7 @@ class APISpec extends Specification { static HttpClient getHttpClient() { if (enableDebugging) { HttpClientConfiguration configuration = new HttpClientConfiguration( - new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)), - false) + new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888))) return HttpClient.createDefault(configuration) } else return HttpClient.createDefault() @@ -189,7 +207,7 @@ class APISpec extends Specification { static ServiceURL getGenericServiceURL(SharedKeyCredentials creds) { PipelineOptions po = new PipelineOptions() - po.client = getHttpClient() + po.withClient(getHttpClient()) HttpPipeline pipeline = StorageURL.createPipeline(creds, po) @@ -205,13 +223,13 @@ class APISpec extends Specification { new URL("http://" + System.getenv().get("ACCOUNT_NAME") + ".blob.core.windows.net"), pipeline) // There should not be more than 5000 containers from these tests for (ContainerItem c : serviceURL.listContainersSegment(null, - new ListContainersOptions(null, containerPrefix, null)).blockingGet() + new ListContainersOptions().withPrefix(containerPrefix), null).blockingGet() .body().containerItems()) { ContainerURL containerURL = serviceURL.createContainerURL(c.name()) if (c.properties().leaseState().equals(LeaseStateType.LEASED)) { - containerURL.breakLease(0, null).blockingGet() + containerURL.breakLease(0, null, null).blockingGet() } - containerURL.delete(null).blockingGet() + containerURL.delete(null, null).blockingGet() } } @@ -223,11 +241,11 @@ class APISpec extends Specification { } static File getRandomFile(long size) { - File file = File.createTempFile(UUID.randomUUID().toString(), ".txt"); - file.deleteOnExit(); - FileOutputStream fos = new FileOutputStream(file); + File file = File.createTempFile(UUID.randomUUID().toString(), ".txt") + file.deleteOnExit() + FileOutputStream fos = new FileOutputStream(file) fos.write(getRandomData(size).array()) - fos.close(); + fos.close() return file } @@ -244,7 +262,7 @@ class APISpec extends Specification { def setup() { cu = primaryServiceURL.createContainerURL(generateContainerName()) - cu.create(null, null).blockingGet() + cu.create(null, null, null).blockingGet() } def cleanup() { @@ -264,10 +282,10 @@ class APISpec extends Specification { * @return * The appropriate etag value to run the current test. */ - def setupBlobMatchCondition(BlobURL bu, ETag match) { + def setupBlobMatchCondition(BlobURL bu, String match) { if (match == receivedEtag) { - BlobGetPropertiesHeaders headers = bu.getProperties(null).blockingGet().headers() - return new ETag(headers.eTag()) + BlobGetPropertiesHeaders headers = bu.getProperties(null, null).blockingGet().headers() + return headers.eTag() } else { return match } @@ -284,12 +302,12 @@ class APISpec extends Specification { * @param leaseID * The signalID. Values should only ever be {@code receivedLeaseID}, {@code garbageLeaseID}, or {@code null}. * @return - * The actual leaseID of the blob if recievedLeaseID is passed, otherwise whatever was passed will be returned. + * The actual leaseAccessConditions of the blob if recievedLeaseID is passed, otherwise whatever was passed will be returned. */ def setupBlobLeaseCondition(BlobURL bu, String leaseID) { BlobAcquireLeaseHeaders headers = null if (leaseID == receivedLeaseID || leaseID == garbageLeaseID) { - headers = bu.acquireLease(null, -1, null).blockingGet().headers() + headers = bu.acquireLease(null, -1, null, null).blockingGet().headers() } if (leaseID == receivedLeaseID) { return headers.leaseId() @@ -298,10 +316,10 @@ class APISpec extends Specification { } } - def setupContainerMatchCondition(ContainerURL cu, ETag match) { + def setupContainerMatchCondition(ContainerURL cu, String match) { if (match == receivedEtag) { - ContainerGetPropertiesHeaders headers = cu.getProperties(null).blockingGet().headers() - return new ETag(headers.eTag()) + ContainerGetPropertiesHeaders headers = cu.getProperties(null, null).blockingGet().headers() + return headers.eTag() } else { return match } @@ -310,19 +328,17 @@ class APISpec extends Specification { def setupContainerLeaseCondition(ContainerURL cu, String leaseID) { if (leaseID == receivedLeaseID) { ContainerAcquireLeaseHeaders headers = - cu.acquireLease(null, -1, null).blockingGet().headers() + cu.acquireLease(null, -1, null, null).blockingGet().headers() return headers.leaseId() } else { return leaseID } } - def waitForCopy(BlobURL bu, BlobStartCopyFromURLResponse response) { - CopyStatusType status = response.headers().copyStatus() - + def waitForCopy(BlobURL bu, CopyStatusType status) { OffsetDateTime start = OffsetDateTime.now() while (status != CopyStatusType.SUCCESS) { - status = bu.getProperties(null).blockingGet().headers().copyStatus() + status = bu.getProperties(null, null).blockingGet().headers().copyStatus() OffsetDateTime currentTime = OffsetDateTime.now() if (status == CopyStatusType.FAILED || currentTime.minusMinutes(1) == start) { throw new Exception("Copy failed or took too long") @@ -360,15 +376,95 @@ class APISpec extends Specification { def enableSoftDelete() { primaryServiceURL.setProperties(new StorageServiceProperties() - .withDeleteRetentionPolicy(new RetentionPolicy().withEnabled(true).withDays(2))) + .withDeleteRetentionPolicy(new RetentionPolicy().withEnabled(true).withDays(2)), null) .blockingGet() sleep(30000) // Wait for the policy to take effect. } def disableSoftDelete() { primaryServiceURL.setProperties(new StorageServiceProperties() - .withDeleteRetentionPolicy(new RetentionPolicy().withEnabled(false))).blockingGet() + .withDeleteRetentionPolicy(new RetentionPolicy().withEnabled(false)), null).blockingGet() sleep(30000) // Wait for the policy to take effect. } + + /* + This method returns a stub of an HttpResponse. This is for when we want to test policies in isolation but don't care + about the status code, so we stub a response that always returns a given value for the status code. We never care + about the number or nature of interactions with this stub. + */ + def getStubResponse(int code) { + return Stub(HttpResponse) { + statusCode() >> code + } + } + + /* + This is for stubbing responses that will actually go through the pipeline and autorest code. Autorest does not seem + to play too nicely with mocked objects and the complex reflection stuff on both ends made it more difficult to work + with than was worth it. + */ + def getStubResponse(int code, Class responseHeadersType) { + return new HttpResponse() { + + @Override + int statusCode() { + return code + } + + @Override + String headerValue(String s) { + return null + } + + @Override + HttpHeaders headers() { + return new HttpHeaders() + } + + @Override + Flowable body() { + return Flowable.empty() + } + + @Override + Single bodyAsByteArray() { + return null + } + + @Override + Single bodyAsString() { + return null + } + + @Override + Object deserializedHeaders() { + return responseHeadersType.getConstructor().newInstance() + } + + @Override + boolean isDecoded() { + return true + } + } + } + + def getContextStubPolicy(int successCode, Class responseHeadersType) { + return Mock(RequestPolicy) { + sendAsync(_) >> { HttpRequest request -> + if (!request.context().getData(defaultContextKey).isPresent()) { + return Single.error(new RuntimeException("Context key not present.")) + } + else { + return Single.just(getStubResponse(successCode, responseHeadersType)) + } + } + } + } + + def getStubFactory(RequestPolicy policy) { + return Mock(RequestPolicyFactory) { + create(*_) >> policy + } + } } diff --git a/src/test/java/com/microsoft/azure/storage/AppendBlobAPITest.groovy b/src/test/java/com/microsoft/azure/storage/AppendBlobAPITest.groovy index 556cb2ae4e6d..3e41d768196f 100644 --- a/src/test/java/com/microsoft/azure/storage/AppendBlobAPITest.groovy +++ b/src/test/java/com/microsoft/azure/storage/AppendBlobAPITest.groovy @@ -17,8 +17,16 @@ package com.microsoft.azure.storage import com.microsoft.azure.storage.blob.* import com.microsoft.azure.storage.blob.models.AppendBlobAppendBlockHeaders +import com.microsoft.azure.storage.blob.models.AppendBlobAppendBlockResponse +import com.microsoft.azure.storage.blob.models.AppendBlobCreateHeaders import com.microsoft.azure.storage.blob.models.AppendBlobCreateResponse +import com.microsoft.azure.storage.blob.models.AppendPositionAccessConditions import com.microsoft.azure.storage.blob.models.BlobGetPropertiesResponse +import com.microsoft.azure.storage.blob.models.BlobHTTPHeaders +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions +import com.microsoft.rest.v2.http.HttpPipeline +import com.microsoft.rest.v2.http.UnexpectedLengthException import com.microsoft.rest.v2.util.FlowableUtil import io.reactivex.Flowable import spock.lang.Unroll @@ -31,13 +39,13 @@ public class AppendBlobAPITest extends APISpec { def setup() { bu = cu.createAppendBlobURL(generateBlobName()) - bu.create(null, null, null).blockingGet() + bu.create(null, null, null, null).blockingGet() } def "Create defaults"() { when: AppendBlobCreateResponse createResponse = - bu.create(null, null, null).blockingGet() + bu.create(null, null, null, null).blockingGet() then: createResponse.statusCode() == 201 @@ -48,10 +56,8 @@ public class AppendBlobAPITest extends APISpec { def "Create error"() { when: - bu.create(null, null, new BlobAccessConditions( - new HTTPAccessConditions(null, null, - new ETag("garbage"), null), - null, null, null)).blockingGet() + bu.create(null, null, new BlobAccessConditions().withModifiedAccessConditions(new ModifiedAccessConditions() + .withIfMatch("garbage")), null).blockingGet() then: thrown(StorageException) @@ -60,12 +66,16 @@ public class AppendBlobAPITest extends APISpec { @Unroll def "Create headers"() { setup: - BlobHTTPHeaders headers = new BlobHTTPHeaders(cacheControl, contentDisposition, contentEncoding, - contentLanguage, contentMD5, contentType) + BlobHTTPHeaders headers = new BlobHTTPHeaders().withBlobCacheControl(cacheControl) + .withBlobContentDisposition(contentDisposition) + .withBlobContentEncoding(contentEncoding) + .withBlobContentLanguage(contentLanguage) + .withBlobContentMD5(contentMD5) + .withBlobContentType(contentType) when: - bu.create(headers, null, null).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + bu.create(headers, null, null, null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: validateBlobHeaders(response.headers(), cacheControl, contentDisposition, contentEncoding, contentLanguage, @@ -90,8 +100,8 @@ public class AppendBlobAPITest extends APISpec { } when: - bu.create(null, metadata, null).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + bu.create(null, metadata, null, null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: response.headers().metadata() == metadata @@ -107,13 +117,14 @@ public class AppendBlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.create(null, null, bac).blockingGet().statusCode() == 201 + bu.create(null, null, bac, null).blockingGet().statusCode() == 201 where: modified | unmodified | match | noneMatch | leaseID @@ -130,12 +141,13 @@ public class AppendBlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.create(null, null, bac).blockingGet() + bu.create(null, null, bac, null).blockingGet() then: thrown(StorageException) @@ -149,40 +161,54 @@ public class AppendBlobAPITest extends APISpec { null | null | null | null | garbageLeaseID } + def "Create context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, AppendBlobCreateHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + bu.create(null, null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Append block defaults"() { setup: AppendBlobAppendBlockHeaders headers = bu.appendBlock(defaultFlowable, defaultDataSize, - null).blockingGet().headers() + null, null).blockingGet().headers() expect: - FlowableUtil.collectBytesInBuffer(bu.download(null, null, false) - .blockingGet().body()).blockingGet().compareTo(defaultData) == 0 + FlowableUtil.collectBytesInBuffer(bu.download(null, null, false, null) + .blockingGet().body(null)).blockingGet().compareTo(defaultData) == 0 validateBasicHeaders(headers) headers.contentMD5() != null headers.blobAppendOffset() != null headers.blobCommittedBlockCount() != null - bu.getProperties(null).blockingGet().headers().blobCommittedBlockCount() == 1 + bu.getProperties(null, null).blockingGet().headers().blobCommittedBlockCount() == 1 } @Unroll def "Append block IA"() { when: - bu.appendBlock(data, dataSize, null).blockingGet() + bu.appendBlock(data, dataSize, null, null).blockingGet() then: - thrown(IllegalArgumentException) + def e = thrown(Exception) + exceptionType.isInstance(e) where: - data | dataSize - null | defaultDataSize - defaultFlowable | defaultDataSize + 1 - defaultFlowable | defaultDataSize - 1 + data | dataSize | exceptionType + null | defaultDataSize | IllegalArgumentException + defaultFlowable | defaultDataSize + 1 | UnexpectedLengthException + defaultFlowable | defaultDataSize - 1 | UnexpectedLengthException } def "Append block empty body"() { when: - bu.appendBlock(Flowable.just(ByteBuffer.wrap(new byte[0])), 0, null).blockingGet() + bu.appendBlock(Flowable.just(ByteBuffer.wrap(new byte[0])), 0, null, null).blockingGet() then: thrown(StorageException) @@ -190,7 +216,7 @@ public class AppendBlobAPITest extends APISpec { def "Append block null body"() { when: - bu.appendBlock(Flowable.just(null), 0, null).blockingGet() + bu.appendBlock(Flowable.just(null), 0, null, null).blockingGet() then: thrown(NullPointerException) // Thrown by Flowable. @@ -201,12 +227,15 @@ public class AppendBlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - new AppendBlobAccessConditions(appendPosE, maxSizeLTE), null) + AppendBlobAccessConditions bac = new AppendBlobAccessConditions() + .withModifiedAccessConditions(new ModifiedAccessConditions().withIfModifiedSince(modified) + .withIfUnmodifiedSince(unmodified).withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) + .withAppendPositionAccessConditions(new AppendPositionAccessConditions() + .withAppendPosition(appendPosE).withMaxSize(maxSizeLTE)) expect: - bu.appendBlock(defaultFlowable, defaultDataSize, bac) + bu.appendBlock(defaultFlowable, defaultDataSize, bac, null) .blockingGet().statusCode() == 201 where: @@ -226,12 +255,16 @@ public class AppendBlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - new AppendBlobAccessConditions(appendPosE, maxSizeLTE), null) + + AppendBlobAccessConditions bac = new AppendBlobAccessConditions() + .withModifiedAccessConditions(new ModifiedAccessConditions().withIfModifiedSince(modified) + .withIfUnmodifiedSince(unmodified).withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) + .withAppendPositionAccessConditions(new AppendPositionAccessConditions() + .withAppendPosition(appendPosE).withMaxSize(maxSizeLTE)) when: - bu.appendBlock(defaultFlowable, defaultDataSize, bac) + bu.appendBlock(defaultFlowable, defaultDataSize, bac, null) .blockingGet().statusCode() then: @@ -253,9 +286,22 @@ public class AppendBlobAPITest extends APISpec { bu = cu.createAppendBlobURL(generateBlobName()) when: - bu.appendBlock(defaultFlowable, defaultDataSize, null).blockingGet() + bu.appendBlock(defaultFlowable, defaultDataSize, null, null).blockingGet() then: thrown(StorageException) } + + def "Append block context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, AppendBlobAppendBlockHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + bu.appendBlock(defaultFlowable, defaultDataSize, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } } diff --git a/src/test/java/com/microsoft/azure/storage/BlobAPITest.groovy b/src/test/java/com/microsoft/azure/storage/BlobAPITest.groovy index 03cbeb1a82fd..f8629b795573 100644 --- a/src/test/java/com/microsoft/azure/storage/BlobAPITest.groovy +++ b/src/test/java/com/microsoft/azure/storage/BlobAPITest.groovy @@ -17,7 +17,7 @@ package com.microsoft.azure.storage import com.microsoft.azure.storage.blob.* import com.microsoft.azure.storage.blob.models.* - +import com.microsoft.rest.v2.http.HttpPipeline import com.microsoft.rest.v2.util.FlowableUtil import io.reactivex.Flowable import spock.lang.Unroll @@ -31,14 +31,14 @@ class BlobAPITest extends APISpec { def setup() { bu = cu.createBlockBlobURL(generateBlobName()) bu.upload(defaultFlowable, defaultDataSize, null, null, - null).blockingGet() + null, null).blockingGet() } def "Download all null"() { when: - DownloadResponse response = bu.download(null, null, false) + DownloadResponse response = bu.download(null, null, false, null) .blockingGet() - ByteBuffer body = FlowableUtil.collectBytesInBuffer(response.body()).blockingGet() + ByteBuffer body = FlowableUtil.collectBytesInBuffer(response.body(null)).blockingGet() BlobDownloadHeaders headers = response.headers() then: @@ -73,11 +73,11 @@ class BlobAPITest extends APISpec { @Unroll def "Download range"() { setup: - BlobRange range = new BlobRange(offset, count) + BlobRange range = new BlobRange().withOffset(offset).withCount(count) when: ByteBuffer body = FlowableUtil.collectBytesInBuffer( - bu.download(range, null, false).blockingGet().body()).blockingGet() + bu.download(range, null, false, null).blockingGet().body(null)).blockingGet() String bodyStr = new String(body.array()) then: @@ -95,12 +95,13 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.download(null, bac, false).blockingGet().statusCode() == 206 + bu.download(null, bac, false, null).blockingGet().statusCode() == 206 where: modified | unmodified | match | noneMatch | leaseID @@ -117,12 +118,13 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.download(null, bac, false).blockingGet().statusCode() == 206 + bu.download(null, bac, false, null).blockingGet().statusCode() == 206 then: thrown(StorageException) @@ -138,7 +140,7 @@ class BlobAPITest extends APISpec { def "Download md5"() { expect: - bu.download(new BlobRange(0, 3), null, true).blockingGet() + bu.download(new BlobRange().withOffset(0).withCount(3), null, true, null).blockingGet() .headers().contentMD5() == MessageDigest.getInstance("MD5").digest(defaultText.substring(0, 3).getBytes()) } @@ -148,15 +150,33 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.download(null, null, false).blockingGet() + bu.download(null, null, false, null).blockingGet() then: thrown(StorageException) } + def "Download context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(206, BlobDownloadHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + bu.download(null, null, false, defaultContext).blockingGet() + + then: + /* + DownloadResponse requires that there be an etag present, but our mock response doesn't give back an etag. The + easiest way to validate this is to ensure the cause of the exception is in fact the absence of the etag. + */ + def e = thrown(IllegalArgumentException) + e.getMessage().contains("eTag") + } + def "Get properties all null"() { when: - BlobGetPropertiesHeaders headers = bu.getProperties(null).blockingGet().headers() + BlobGetPropertiesHeaders headers = bu.getProperties(null, null).blockingGet().headers() then: validateBasicHeaders(headers) @@ -195,12 +215,13 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.getProperties(bac).blockingGet().statusCode() == 200 + bu.getProperties(bac, null).blockingGet().statusCode() == 200 where: modified | unmodified | match | noneMatch | leaseID @@ -217,12 +238,12 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) - + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.getProperties(bac).blockingGet() + bu.getProperties(bac, null).blockingGet() then: thrown(StorageException) @@ -241,15 +262,28 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.getProperties(null).blockingGet() + bu.getProperties(null, null).blockingGet() then: thrown(StorageException) } + def "Get properties context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobGetPropertiesHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + bu.getProperties(null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Set HTTP headers null"() { setup: - BlobSetHTTPHeadersResponse response = bu.setHTTPHeaders(null, null).blockingGet() + BlobSetHTTPHeadersResponse response = bu.setHTTPHeaders(null, null, null).blockingGet() expect: response.statusCode() == 200 @@ -260,11 +294,16 @@ class BlobAPITest extends APISpec { @Unroll def "Set HTTP headers headers"() { setup: - BlobHTTPHeaders putHeaders = new BlobHTTPHeaders(cacheControl, contentDisposition, contentEncoding, - contentLanguage, contentMD5, contentType) - bu.setHTTPHeaders(putHeaders, null).blockingGet() + BlobHTTPHeaders putHeaders = new BlobHTTPHeaders().withBlobCacheControl(cacheControl) + .withBlobContentDisposition(contentDisposition) + .withBlobContentEncoding(contentEncoding) + .withBlobContentLanguage(contentLanguage) + .withBlobContentMD5(contentMD5) + .withBlobContentType(contentType) + bu.setHTTPHeaders(putHeaders, null, null).blockingGet() + BlobGetPropertiesHeaders receivedHeaders = - bu.getProperties(null).blockingGet().headers() + bu.getProperties(null, null).blockingGet().headers() expect: validateBlobHeaders(receivedHeaders, cacheControl, contentDisposition, contentEncoding, contentLanguage, @@ -277,17 +316,20 @@ class BlobAPITest extends APISpec { } + + @Unroll def "Set HTTP headers AC"() { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.setHTTPHeaders(null, bac).blockingGet().statusCode() == 200 + bu.setHTTPHeaders(null, bac, null).blockingGet().statusCode() == 200 where: modified | unmodified | match | noneMatch | leaseID @@ -304,12 +346,13 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.setHTTPHeaders(null, bac).blockingGet() + bu.setHTTPHeaders(null, bac, null).blockingGet() then: thrown(StorageException) @@ -328,18 +371,31 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.setHTTPHeaders(null, null).blockingGet() + bu.setHTTPHeaders(null, null, null).blockingGet() then: thrown(StorageException) } + def "Set HTTP headers context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobSetHTTPHeadersHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + bu.setHTTPHeaders(null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Set metadata all null"() { setup: - BlobSetMetadataResponse response = bu.setMetadata(null, null).blockingGet() + BlobSetMetadataResponse response = bu.setMetadata(null, null, null).blockingGet() expect: - bu.getProperties(null).blockingGet().headers().metadata().size() == 0 + bu.getProperties(null, null).blockingGet().headers().metadata().size() == 0 response.statusCode() == 200 validateBasicHeaders(response.headers()) response.headers().isServerEncrypted() @@ -357,8 +413,8 @@ class BlobAPITest extends APISpec { } expect: - bu.setMetadata(metadata, null).blockingGet().statusCode() == statusCode - bu.getProperties(null).blockingGet().headers().metadata() == metadata + bu.setMetadata(metadata, null, null).blockingGet().statusCode() == statusCode + bu.getProperties(null, null).blockingGet().headers().metadata() == metadata where: key1 | value1 | key2 | value2 || statusCode @@ -371,12 +427,13 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.setMetadata(null, bac).blockingGet().statusCode() == 200 + bu.setMetadata(null, bac, null).blockingGet().statusCode() == 200 where: modified | unmodified | match | noneMatch | leaseID @@ -394,12 +451,13 @@ class BlobAPITest extends APISpec { noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.setMetadata(null, bac).blockingGet() + bu.setMetadata(null, bac, null).blockingGet() then: thrown(StorageException) @@ -418,21 +476,34 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.setMetadata(null, null).blockingGet() + bu.setMetadata(null, null, null).blockingGet() then: thrown(StorageException) } + def "Set metadata context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobSetMetadataHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + bu.setMetadata(null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + @Unroll def "Acquire lease"() { setup: BlobAcquireLeaseHeaders headers = - bu.acquireLease(proposedID, leaseTime, null) + bu.acquireLease(proposedID, leaseTime, null, null) .blockingGet().headers() when: - BlobGetPropertiesHeaders properties = bu.getProperties(null).blockingGet() + BlobGetPropertiesHeaders properties = bu.getProperties(null, null).blockingGet() .headers() then: @@ -452,10 +523,11 @@ class BlobAPITest extends APISpec { def "Acquire lease AC"() { setup: match = setupBlobMatchCondition(bu, match) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) expect: - bu.acquireLease(null, -1, hac).blockingGet().statusCode() == 201 + bu.acquireLease(null, -1, mac, null).blockingGet().statusCode() == 201 where: modified | unmodified | match | noneMatch @@ -470,10 +542,11 @@ class BlobAPITest extends APISpec { def "Acquire lease AC fail"() { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) when: - bu.acquireLease(null, -1, hac).blockingGet() + bu.acquireLease(null, -1, mac, null).blockingGet() then: thrown(StorageException) @@ -491,21 +564,34 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.acquireLease(null, 20, null).blockingGet() + bu.acquireLease(null, 20, null, null).blockingGet() then: thrown(StorageException) } + def "Acquire lease context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, BlobAcquireLeaseHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + bu.acquireLease(null, 20, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Renew lease"() { setup: String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) Thread.sleep(16000) // Wait for the lease to expire to ensure we are actually renewing it - BlobRenewLeaseHeaders headers = bu.renewLease(leaseID, null).blockingGet().headers() + BlobRenewLeaseHeaders headers = bu.renewLease(leaseID, null, null).blockingGet().headers() expect: - bu.getProperties(null).blockingGet().headers().leaseState() + bu.getProperties(null, null).blockingGet().headers().leaseState() .equals(LeaseStateType.LEASED) validateBasicHeaders(headers) headers.leaseId() != null @@ -516,10 +602,11 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) expect: - bu.renewLease(leaseID, hac).blockingGet().statusCode() == 200 + bu.renewLease(leaseID, mac, null).blockingGet().statusCode() == 200 where: modified | unmodified | match | noneMatch @@ -534,10 +621,11 @@ class BlobAPITest extends APISpec { def "Renew lease AC fail"() { noneMatch = setupBlobMatchCondition(bu, noneMatch) String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) when: - bu.renewLease(leaseID, hac).blockingGet() + bu.renewLease(leaseID, mac, null).blockingGet() then: thrown(StorageException) @@ -555,20 +643,34 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.renewLease("id", null).blockingGet() + bu.renewLease("id", null, null).blockingGet() then: thrown(StorageException) } + def "Renew lease context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobRenewLeaseHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.renewLease("id", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Release lease"() { setup: String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) - BlobReleaseLeaseHeaders headers = bu.releaseLease(leaseID, null).blockingGet().headers() + BlobReleaseLeaseHeaders headers = bu.releaseLease(leaseID, null, null).blockingGet().headers() expect: - bu.getProperties(null).blockingGet().headers().leaseState() == LeaseStateType.AVAILABLE + bu.getProperties(null, null).blockingGet().headers().leaseState() == LeaseStateType.AVAILABLE validateBasicHeaders(headers) } @@ -577,10 +679,11 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) expect: - bu.releaseLease(leaseID, hac).blockingGet().statusCode() == 200 + bu.releaseLease(leaseID, mac, null).blockingGet().statusCode() == 200 where: modified | unmodified | match | noneMatch @@ -596,10 +699,11 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) when: - bu.releaseLease(leaseID, hac).blockingGet() + bu.releaseLease(leaseID, mac, null).blockingGet() then: thrown(StorageException) @@ -617,19 +721,33 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.releaseLease("id", null).blockingGet() + bu.releaseLease("id", null, null).blockingGet() then: thrown(StorageException) } + def "Release lease context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobReleaseLeaseHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.releaseLease("id", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + @Unroll def "Break lease"() { setup: - bu.acquireLease(UUID.randomUUID().toString(), leaseTime, null).blockingGet() + bu.acquireLease(UUID.randomUUID().toString(), leaseTime, null, null).blockingGet() - BlobBreakLeaseHeaders headers = bu.breakLease(breakPeriod, null).blockingGet().headers() - LeaseStateType state = bu.getProperties(null).blockingGet().headers().leaseState() + BlobBreakLeaseHeaders headers = bu.breakLease(breakPeriod, null, null).blockingGet().headers() + LeaseStateType state = bu.getProperties(null, null).blockingGet().headers().leaseState() expect: state == LeaseStateType.BROKEN || state == LeaseStateType.BREAKING @@ -641,7 +759,6 @@ class BlobAPITest extends APISpec { -1 | null | 0 -1 | 20 | 25 20 | 15 | 16 - } @Unroll @@ -649,10 +766,11 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) expect: - bu.breakLease(null, hac).blockingGet().statusCode() == 202 + bu.breakLease(null, mac, null).blockingGet().statusCode() == 202 where: modified | unmodified | match | noneMatch @@ -668,10 +786,11 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) when: - bu.breakLease(null, hac).blockingGet() + bu.breakLease(null, mac, null).blockingGet() then: thrown(StorageException) @@ -689,23 +808,37 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.breakLease(null, null).blockingGet() + bu.breakLease(null, null, null).blockingGet() then: thrown(StorageException) } + def "Break lease context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(202, BlobBreakLeaseHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.breakLease(18, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Change lease"() { setup: String leaseID = - bu.acquireLease(UUID.randomUUID().toString(), 15, null).blockingGet() + bu.acquireLease(UUID.randomUUID().toString(), 15, null, null).blockingGet() .headers().leaseId() - BlobChangeLeaseHeaders headers = bu.changeLease(leaseID, UUID.randomUUID().toString(), null) + BlobChangeLeaseHeaders headers = bu.changeLease(leaseID, UUID.randomUUID().toString(), null, null) .blockingGet().headers() leaseID = headers.leaseId() expect: - bu.releaseLease(leaseID, null).blockingGet().statusCode() == 200 + bu.releaseLease(leaseID, null, null).blockingGet().statusCode() == 200 validateBasicHeaders(headers) } @@ -714,10 +847,11 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) expect: - bu.changeLease(leaseID, UUID.randomUUID().toString(), hac).blockingGet().statusCode() == 200 + bu.changeLease(leaseID, UUID.randomUUID().toString(), mac, null).blockingGet().statusCode() == 200 where: modified | unmodified | match | noneMatch @@ -733,10 +867,11 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) when: - bu.changeLease(leaseID, UUID.randomUUID().toString(), hac).blockingGet() + bu.changeLease(leaseID, UUID.randomUUID().toString(), mac, null).blockingGet() then: thrown(StorageException) @@ -754,19 +889,33 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.changeLease("id", "id", null).blockingGet() + bu.changeLease("id", "id", null, null).blockingGet() then: thrown(StorageException) } + def "Change lease context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobChangeLeaseHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.changeLease("id", "newId", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Snapshot"() { when: - BlobCreateSnapshotHeaders headers = bu.createSnapshot(null, null) + BlobCreateSnapshotHeaders headers = bu.createSnapshot(null, null, null) .blockingGet().headers() then: - bu.withSnapshot(headers.snapshot()).getProperties(null).blockingGet().statusCode() == 200 + bu.withSnapshot(headers.snapshot()).getProperties(null, null).blockingGet().statusCode() == 200 validateBasicHeaders(headers) } @@ -781,12 +930,12 @@ class BlobAPITest extends APISpec { metadata.put(key2, value2) } - BlobCreateSnapshotResponse response = bu.createSnapshot(metadata, null).blockingGet() + BlobCreateSnapshotResponse response = bu.createSnapshot(metadata, null, null).blockingGet() expect: response.statusCode() == 201 bu.withSnapshot(response.headers().snapshot()) - .getProperties(null).blockingGet().headers().metadata() == metadata + .getProperties(null, null).blockingGet().headers().metadata() == metadata where: key1 | value1 | key2 | value2 || statusCode @@ -799,12 +948,13 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.createSnapshot(null, bac).blockingGet().statusCode() == 201 + bu.createSnapshot(null, bac, null).blockingGet().statusCode() == 201 where: modified | unmodified | match | noneMatch | leaseID @@ -821,12 +971,13 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.createSnapshot(null, bac).blockingGet() + bu.createSnapshot(null, bac, null).blockingGet() then: thrown(StorageException) @@ -845,24 +996,38 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.createSnapshot(null, null).blockingGet() + bu.createSnapshot(null, null, null).blockingGet() then: thrown(StorageException) } + def "Snapshot context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, BlobCreateSnapshotHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.createSnapshot(null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Copy"() { setup: BlobURL bu2 = cu.createBlockBlobURL(generateBlobName()) BlobStartCopyFromURLHeaders headers = - bu2.startCopyFromURL(bu.toURL(), null, null, null) + bu2.startCopyFromURL(bu.toURL(), null, null, null, null) .blockingGet().headers() when: - while (bu2.getProperties(null).blockingGet().headers().copyStatus() == CopyStatusType.PENDING) { + while (bu2.getProperties(null, null).blockingGet().headers().copyStatus() == CopyStatusType.PENDING) { sleep(1000) } - BlobGetPropertiesHeaders headers2 = bu2.getProperties(null).blockingGet().headers() + BlobGetPropertiesHeaders headers2 = bu2.getProperties(null, null).blockingGet().headers() then: headers2.copyStatus() == CopyStatusType.SUCCESS @@ -886,12 +1051,12 @@ class BlobAPITest extends APISpec { } BlobStartCopyFromURLResponse response = - bu2.startCopyFromURL(bu.toURL(), metadata, null, null) + bu2.startCopyFromURL(bu.toURL(), metadata, null, null, null) .blockingGet() - waitForCopy(bu2, response) + waitForCopy(bu2, response.headers().copyStatus()) expect: - bu2.getProperties(null).blockingGet().headers().metadata() == metadata + bu2.getProperties(null, null).blockingGet().headers().metadata() == metadata where: key1 | value1 | key2 | value2 || statusCode @@ -904,10 +1069,11 @@ class BlobAPITest extends APISpec { setup: BlobURL bu2 = cu.createBlockBlobURL(generateBlobName()) match = setupBlobMatchCondition(bu, match) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) expect: - bu2.startCopyFromURL(bu.toURL(), null, hac, null).blockingGet().statusCode() == 202 + bu2.startCopyFromURL(bu.toURL(), null, mac, null, null).blockingGet().statusCode() == 202 where: modified | unmodified | match | noneMatch | leaseID @@ -923,10 +1089,11 @@ class BlobAPITest extends APISpec { setup: BlobURL bu2 = cu.createBlockBlobURL(generateBlobName()) noneMatch = setupBlobMatchCondition(bu, noneMatch) - def hac = new HTTPAccessConditions(modified, unmodified, match, noneMatch) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) when: - bu2.startCopyFromURL(bu.toURL(), null, hac, null).blockingGet() + bu2.startCopyFromURL(bu.toURL(), null, mac, null, null).blockingGet() then: thrown(StorageException) @@ -944,15 +1111,16 @@ class BlobAPITest extends APISpec { setup: BlobURL bu2 = cu.createBlockBlobURL(generateBlobName()) bu2.upload(defaultFlowable, defaultDataSize, null, null, - null).blockingGet() + null, null).blockingGet() match = setupBlobMatchCondition(bu2, match) leaseID = setupBlobLeaseCondition(bu2, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu2.startCopyFromURL(bu.toURL(), null, null, bac) + bu2.startCopyFromURL(bu.toURL(), null, null, bac, null) .blockingGet().statusCode() == 202 where: @@ -970,15 +1138,16 @@ class BlobAPITest extends APISpec { setup: BlobURL bu2 = cu.createBlockBlobURL(generateBlobName()) bu2.upload(defaultFlowable, defaultDataSize, null, null, - null).blockingGet() + null, null).blockingGet() noneMatch = setupBlobMatchCondition(bu2, noneMatch) setupBlobLeaseCondition(bu2, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu2.startCopyFromURL(bu.toURL(), null, null, bac).blockingGet() + bu2.startCopyFromURL(bu.toURL(), null, null, bac, null).blockingGet() then: thrown(StorageException) @@ -998,31 +1167,45 @@ class BlobAPITest extends APISpec { when: bu.startCopyFromURL(new URL("http://www.error.com"), - null, null, null).blockingGet() + null, null, null, null).blockingGet() then: thrown(StorageException) } + def "Copy context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(202, BlobStartCopyFromURLHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.startCopyFromURL(new URL("http://www.example.com"), null, null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Abort copy"() { setup: // Data has to be large enough and copied between accounts to give us enough time to abort ByteBuffer data = getRandomData(8 * 1024 * 1024) bu.toBlockBlobURL() - .upload(Flowable.just(data), 8 * 1024 * 1024, null, null, null) + .upload(Flowable.just(data), 8 * 1024 * 1024, null, null, null, null) .blockingGet() // So we don't have to create a SAS. - cu.setAccessPolicy(PublicAccessType.BLOB, null, null).blockingGet() + cu.setAccessPolicy(PublicAccessType.BLOB, null, null, null).blockingGet() ContainerURL cu2 = alternateServiceURL.createContainerURL(generateBlobName()) - cu2.create(null, null).blockingGet() + cu2.create(null, null, null).blockingGet() BlobURL bu2 = cu2.createBlobURL(generateBlobName()) when: String copyID = - bu2.startCopyFromURL(bu.toURL(), null, null, null) + bu2.startCopyFromURL(bu.toURL(), null, null, null, null) .blockingGet().headers().copyId() - BlobAbortCopyFromURLResponse response = bu2.abortCopyFromURL(copyID, null).blockingGet() + BlobAbortCopyFromURLResponse response = bu2.abortCopyFromURL(copyID, null, null).blockingGet() BlobAbortCopyFromURLHeaders headers = response.headers() then: @@ -1031,7 +1214,7 @@ class BlobAPITest extends APISpec { headers.version() != null headers.date() != null // Normal test cleanup will not clean up containers in the alternate account. - cu2.delete(null).blockingGet().statusCode() == 202 + cu2.delete(null, null).blockingGet().statusCode() == 202 } def "Abort copy lease"() { @@ -1039,59 +1222,60 @@ class BlobAPITest extends APISpec { // Data has to be large enough and copied between accounts to give us enough time to abort ByteBuffer data = getRandomData(8 * 1024 * 1024) bu.toBlockBlobURL() - .upload(Flowable.just(data), 8 * 1024 * 1024, null, null, null) + .upload(Flowable.just(data), 8 * 1024 * 1024, null, null, null, null) .blockingGet() // So we don't have to create a SAS. - cu.setAccessPolicy(PublicAccessType.BLOB, null, null).blockingGet() + cu.setAccessPolicy(PublicAccessType.BLOB, null, null, null).blockingGet() ContainerURL cu2 = alternateServiceURL.createContainerURL(generateBlobName()) - cu2.create(null, null).blockingGet() + cu2.create(null, null, null).blockingGet() BlockBlobURL bu2 = cu2.createBlockBlobURL(generateBlobName()) - bu2.upload(defaultFlowable, defaultDataSize, null, null, null) + bu2.upload(defaultFlowable, defaultDataSize, null, null, null, null) .blockingGet() String leaseID = setupBlobLeaseCondition(bu2, receivedLeaseID) when: String copyID = bu2.startCopyFromURL(bu.toURL(), null, null, - new BlobAccessConditions(null, new LeaseAccessConditions(leaseID), - null, null)) + new BlobAccessConditions().withLeaseAccessConditions(new LeaseAccessConditions() + .withLeaseId(leaseID)), null) .blockingGet().headers().copyId() then: - bu2.abortCopyFromURL(copyID, new LeaseAccessConditions(leaseID)).blockingGet().statusCode() == 204 + bu2.abortCopyFromURL(copyID, new LeaseAccessConditions().withLeaseId(leaseID), null) + .blockingGet().statusCode() == 204 // Normal test cleanup will not clean up containers in the alternate account. - cu2.delete(null).blockingGet() + cu2.delete(null, null).blockingGet() } def "Abort copy lease fail"() { // Data has to be large enough and copied between accounts to give us enough time to abort ByteBuffer data = getRandomData(8 * 1024 * 1024) bu.toBlockBlobURL() - .upload(Flowable.just(data), 8 * 1024 * 1024, null, null, null) + .upload(Flowable.just(data), 8 * 1024 * 1024, null, null, null, null) .blockingGet() // So we don't have to create a SAS. - cu.setAccessPolicy(PublicAccessType.BLOB, null, null).blockingGet() + cu.setAccessPolicy(PublicAccessType.BLOB, null, null, null).blockingGet() ContainerURL cu2 = alternateServiceURL.createContainerURL(generateBlobName()) - cu2.create(null, null).blockingGet() + cu2.create(null, null, null).blockingGet() BlockBlobURL bu2 = cu2.createBlockBlobURL(generateBlobName()) - bu2.upload(defaultFlowable, defaultDataSize, null, null, null) + bu2.upload(defaultFlowable, defaultDataSize, null, null, null, null) .blockingGet() String leaseID = setupBlobLeaseCondition(bu2, receivedLeaseID) when: String copyID = bu2.startCopyFromURL(bu.toURL(), null, null, - new BlobAccessConditions(null, new LeaseAccessConditions(leaseID), - null, null)) + new BlobAccessConditions().withLeaseAccessConditions(new LeaseAccessConditions() + .withLeaseId(leaseID)), null) .blockingGet().headers().copyId() - bu2.abortCopyFromURL(copyID, new LeaseAccessConditions(garbageLeaseID)).blockingGet() + bu2.abortCopyFromURL(copyID, new LeaseAccessConditions().withLeaseId(garbageLeaseID), null).blockingGet() then: def e = thrown(StorageException) e.statusCode() == 412 - cu2.delete(null).blockingGet() + cu2.delete(null, null).blockingGet() } def "Abort copy error"() { @@ -1099,15 +1283,29 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.abortCopyFromURL("id", null).blockingGet() + bu.abortCopyFromURL("id", null, null).blockingGet() then: thrown(StorageException) } + def "Abort copy context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(204, BlobAbortCopyFromURLHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.abortCopyFromURL("id", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Delete"() { when: - BlobDeleteResponse response = bu.delete(null, null).blockingGet() + BlobDeleteResponse response = bu.delete(null, null, null).blockingGet() BlobDeleteHeaders headers = response.headers() then: @@ -1120,17 +1318,17 @@ class BlobAPITest extends APISpec { @Unroll def "Delete options"() { setup: - bu.createSnapshot(null, null).blockingGet() + bu.createSnapshot(null, null, null).blockingGet() // Create an extra blob so the list isn't empty (null) when we delete base blob, too BlockBlobURL bu2 = cu.createBlockBlobURL(generateBlobName()) - bu2.upload(defaultFlowable, defaultDataSize, null, null, null) + bu2.upload(defaultFlowable, defaultDataSize, null, null, null, null) .blockingGet() when: - bu.delete(option, null).blockingGet() + bu.delete(option, null, null).blockingGet() then: - cu.listBlobsFlatSegment(null, null).blockingGet() + cu.listBlobsFlatSegment(null, null, null).blockingGet() .body().segment().blobItems().size() == blobsRemaining where: @@ -1144,12 +1342,13 @@ class BlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.delete(DeleteSnapshotsOptionType.INCLUDE, bac).blockingGet().statusCode() == 202 + bu.delete(DeleteSnapshotsOptionType.INCLUDE, bac, null).blockingGet().statusCode() == 202 where: modified | unmodified | match | noneMatch | leaseID @@ -1166,12 +1365,13 @@ class BlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.delete(DeleteSnapshotsOptionType.INCLUDE, bac).blockingGet() + bu.delete(DeleteSnapshotsOptionType.INCLUDE, bac, null).blockingGet() then: thrown(StorageException) @@ -1190,30 +1390,44 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.delete(null, null).blockingGet() + bu.delete(null, null, null).blockingGet() then: thrown(StorageException) } + def "Delete context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(202, BlobDeleteHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.delete(null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + @Unroll def "Set tier block blob"() { setup: ContainerURL cu = blobStorageServiceURL.createContainerURL(generateContainerName()) BlockBlobURL bu = cu.createBlockBlobURL(generateBlobName()) - cu.create(null, null).blockingGet() - bu.upload(defaultFlowable, defaultData.remaining(), null, null, null) + cu.create(null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultData.remaining(), null, null, null, null) .blockingGet() when: - BlobSetTierResponse initialResponse = bu.setTier(tier).blockingGet() + BlobSetTierResponse initialResponse = bu.setTier(tier, null, null).blockingGet() then: initialResponse.statusCode() == 200 || initialResponse.statusCode() == 202 initialResponse.headers().version() != null initialResponse.headers().requestId() != null - bu.getProperties(null).blockingGet().headers().accessTier() == tier.toString() - cu.listBlobsFlatSegment(null, null).blockingGet().body().segment().blobItems().get(0) + bu.getProperties(null, null).blockingGet().headers().accessTier() == tier.toString() + cu.listBlobsFlatSegment(null, null, null).blockingGet().body().segment().blobItems().get(0) .properties().accessTier() == tier where: @@ -1228,17 +1442,17 @@ class BlobAPITest extends APISpec { setup: ContainerURL cu = premiumServiceURL.createContainerURL(generateContainerName()) PageBlobURL bu = cu.createPageBlobURL(generateBlobName()) - cu.create(null, null).blockingGet() - bu.create(512, null, null, null, null).blockingGet() + cu.create(null, null, null).blockingGet() + bu.create(512, null, null, null, null, null).blockingGet() when: - bu.setTier(tier).blockingGet() + bu.setTier(tier, null, null).blockingGet() then: - bu.getProperties(null).blockingGet().headers().accessTier() == tier.toString() - cu.listBlobsFlatSegment(null, null).blockingGet().body().segment().blobItems().get(0) + bu.getProperties(null, null).blockingGet().headers().accessTier() == tier.toString() + cu.listBlobsFlatSegment(null, null, null).blockingGet().body().segment().blobItems().get(0) .properties().accessTier() == tier - cu.delete(null).blockingGet() + cu.delete(null, null).blockingGet() where: tier | _ @@ -1255,19 +1469,19 @@ class BlobAPITest extends APISpec { setup: ContainerURL cu = blobStorageServiceURL.createContainerURL(generateBlobName()) BlockBlobURL bu = cu.createBlockBlobURL(generateBlobName()) - cu.create(null, null).blockingGet() - bu.upload(defaultFlowable, defaultDataSize, null, null, null).blockingGet() + cu.create(null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() when: - boolean inferred1 = bu.getProperties(null).blockingGet().headers().accessTierInferred() - Boolean inferredList1 = cu.listBlobsFlatSegment(null, null).blockingGet().body().segment() + boolean inferred1 = bu.getProperties(null, null).blockingGet().headers().accessTierInferred() + Boolean inferredList1 = cu.listBlobsFlatSegment(null, null, null).blockingGet().body().segment() .blobItems().get(0).properties().accessTierInferred() - bu.setTier(AccessTier.HOT).blockingGet() + bu.setTier(AccessTier.HOT, null, null).blockingGet() - BlobGetPropertiesHeaders headers = bu.getProperties(null).blockingGet().headers() + BlobGetPropertiesHeaders headers = bu.getProperties(null, null).blockingGet().headers() Boolean inferred2 = headers.accessTierInferred() - Boolean inferredList2 = cu.listBlobsFlatSegment(null, null).blockingGet().body().segment() + Boolean inferredList2 = cu.listBlobsFlatSegment(null, null, null).blockingGet().body().segment() .blobItems().get(0).properties().accessTierInferred() then: @@ -1282,16 +1496,16 @@ class BlobAPITest extends APISpec { setup: ContainerURL cu = blobStorageServiceURL.createContainerURL(generateBlobName()) BlockBlobURL bu = cu.createBlockBlobURL(generateBlobName()) - cu.create(null, null).blockingGet() - bu.upload(defaultFlowable, defaultDataSize, null, null, null).blockingGet() + cu.create(null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() when: - bu.setTier(sourceTier).blockingGet() - bu.setTier(destTier).blockingGet() + bu.setTier(sourceTier, null, null).blockingGet() + bu.setTier(destTier, null, null).blockingGet() then: - bu.getProperties(null).blockingGet().headers().archiveStatus() == status.toString() - cu.listBlobsFlatSegment(null, null).blockingGet().body().segment().blobItems() + bu.getProperties(null, null).blockingGet().headers().archiveStatus() == status.toString() + cu.listBlobsFlatSegment(null, null, null).blockingGet().body().segment().blobItems() .get(0).properties().archiveStatus() where: @@ -1304,11 +1518,11 @@ class BlobAPITest extends APISpec { setup: ContainerURL cu = blobStorageServiceURL.createContainerURL(generateBlobName()) BlockBlobURL bu = cu.createBlockBlobURL(generateBlobName()) - cu.create(null, null).blockingGet() - bu.upload(defaultFlowable, defaultDataSize, null, null, null).blockingGet() + cu.create(null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() when: - bu.setTier(AccessTier.fromString("garbage")).blockingGet() + bu.setTier(AccessTier.fromString("garbage"), null, null).blockingGet() then: def e = thrown(StorageException) @@ -1317,20 +1531,63 @@ class BlobAPITest extends APISpec { def "Set tier illegal argument"() { when: - bu.setTier(null) + bu.setTier(null, null, null) then: thrown(IllegalArgumentException) } + def "Set tier lease"() { + setup: + ContainerURL cu = blobStorageServiceURL.createContainerURL(generateBlobName()) + BlockBlobURL bu = cu.createBlockBlobURL(generateBlobName()) + cu.create(null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() + def leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) + + when: + bu.setTier(AccessTier.HOT, new LeaseAccessConditions().withLeaseId(leaseID), null).blockingGet() + + then: + notThrown(StorageException) + } + + def "Set tier lease fail"() { + setup: + ContainerURL cu = blobStorageServiceURL.createContainerURL(generateBlobName()) + BlockBlobURL bu = cu.createBlockBlobURL(generateBlobName()) + cu.create(null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() + + when: + bu.setTier(AccessTier.HOT, new LeaseAccessConditions().withLeaseId("garbage"), null).blockingGet() + + then: + thrown(StorageException) + } + + def "Set tier context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(202, BlobSetTierHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.setTier(AccessTier.HOT, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Undelete"() { setup: enableSoftDelete() - bu.delete(null, null).blockingGet() + bu.delete(null, null, null).blockingGet() when: - def response = bu.undelete().blockingGet() - bu.getProperties(null).blockingGet() + def response = bu.undelete(null).blockingGet() + bu.getProperties(null, null).blockingGet() then: notThrown(StorageException) @@ -1345,15 +1602,29 @@ class BlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.undelete().blockingGet() + bu.undelete(null).blockingGet() then: thrown(StorageException) } + def "Undelete context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobUndeleteHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.undelete(defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Get account info"() { when: - def response = primaryServiceURL.getAccountInfo().blockingGet() + def response = primaryServiceURL.getAccountInfo(null).blockingGet() then: response.headers().date() != null @@ -1368,9 +1639,23 @@ class BlobAPITest extends APISpec { ServiceURL serviceURL = new ServiceURL(primaryServiceURL.toURL(), StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions())) serviceURL.createContainerURL(generateContainerName()).createBlobURL(generateBlobName()) - .getAccountInfo().blockingGet() + .getAccountInfo(null).blockingGet() then: thrown(StorageException) } + + def "Get account info context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlobGetAccountInfoHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.getAccountInfo(defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } } diff --git a/src/test/java/com/microsoft/azure/storage/BlobStorageAPITests.java b/src/test/java/com/microsoft/azure/storage/BlobStorageAPITests.java deleted file mode 100644 index f28a8b880ad0..000000000000 --- a/src/test/java/com/microsoft/azure/storage/BlobStorageAPITests.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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; - -import com.microsoft.azure.storage.blob.*; -import com.microsoft.rest.v2.RestException; -import com.microsoft.azure.storage.blob.models.*; -import com.microsoft.rest.v2.http.*; -import com.microsoft.rest.v2.util.FlowableUtil; -import io.reactivex.Flowable; -import io.reactivex.functions.BiConsumer; -import org.junit.Assert; -import org.junit.Test; - -import java.io.*; -import java.net.MalformedURLException; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.URL; -import java.nio.ByteBuffer; -import java.security.InvalidKeyException; -import java.time.OffsetDateTime; -import java.util.*; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.*; - -public class BlobStorageAPITests { - - @Test - public void TestPutBlobBasic() throws IOException, InvalidKeyException, InterruptedException { - /** - * This library uses the Azure Rest Pipeline to make its requests. Details on this pipeline can be found here: - * https://github.com/Azure/azure-pipeline-go/blob/master/pipeline/doc.go All references to HttpPipeline and - * the like refer to this structure. - * This library uses Microsoft AutoRest to generate the protocol layer off of the Swagger API spec of the - * blob service. All files in the implementation and models folders as well as the Interfaces in the root - * directory are auto-generated using this tool. - * This library's paradigm is centered around the URL object. A URL is constructed to a resource, such as - * BlobURL. This is solely a reference to a location; the existence of a BlobURL does not indicate the existence - * of a blob or hold any state related to the blob. The URL objects define methods for all operations related - * to that resource (or will eventually; some are not supported in the library yet). - * Several structures are defined on top of the auto-generated protocol layer to logically group items or - * concepts relevant to a given operation or resource. This both reduces the length of the parameter list - * and provides some coherency and relationship of ideas to aid the developer, improving efficiency and - * discoverability. - * In this sample test, we demonstrate the use of all APIs that are currently implemented. They have been tested - * to work in these cases, but they have not been thoroughly tested. More advanced operations performed by - * specifying or modifying calls in this test are not guaranteed to work. APIs not shown here are not guaranteed - * to work. Any reports on bugs found will be welcomed and addressed. - */ - - - // Creating a pipeline requires a credentials object and a structure of pipeline options to customize the behavior. - // Set your system environment variables of ACCOUNT_NAME and ACCOUNT_KEY to pull the appropriate credentials. - // Credentials may be SharedKey as shown here or Anonymous as shown below. - SharedKeyCredentials creds = new SharedKeyCredentials(System.getenv().get("ACCOUNT_NAME"), - System.getenv().get("ACCOUNT_KEY")); - - // Currently only the default PipelineOptions are supported. - PipelineOptions po = new PipelineOptions(); - HttpClientConfiguration configuration = new HttpClientConfiguration( - new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)), false); - po.client = HttpClient.createDefault();//configuration); - HttpPipeline pipeline = StorageURL.createPipeline(creds, po); - - // Create a reference to the service. - ServiceURL su = new ServiceURL( - new URL("http://" + System.getenv().get("ACCOUNT_NAME") + ".blob.core.windows.net"), pipeline); - - // Create a reference to a container. Using the ServiceURL to create the ContainerURL appends - // the container name to the ServiceURL. A ContainerURL may also be created by calling its - // constructor with a full path to the container and a pipeline. - String containerName = "javatestcontainer" + System.currentTimeMillis(); - ContainerURL cu = su.createContainerURL(containerName); - - // Create a reference to a blob. Same pattern as containers. - BlockBlobURL bu = cu.createBlockBlobURL("javatestblob"); - try { - // Calls to blockingGet force the call to be synchronous. This whole test is synchronous. - // APIs will typically return a RestResponse<*HeadersType*, *BodyType*>. It is therefore possible to - // retrieve the headers and the deserialized body of every request. If there is no body in the request, - // the body type will be Void. - // Errors are thrown as exceptions in the synchronous (blockingGet) case. - - // Create the container. NOTE: Metadata is not currently supported on any resource. - - cu.create(null, PublicAccessType.BLOB).blockingGet(); - - // Create the blob with a single put. See below for the stageBlock(List) scenario. - bu.upload(Flowable.just(ByteBuffer.wrap(new byte[]{0, 0, 0})), 3, null, - null, null).blockingGet(); - - // Download the blob contents. - Flowable data; - byte[] dataByte; - - - // SAS ----------------------------- - // Parses a URL into its constituent components. This structure's URL fields may be modified. - BlobURLParts parts = URLParser.parse(bu.toURL()); - - // Construct the AccountSASSignatureValues values object. This encapsulates all the values needed to create an AccountSASSignatureValues. - AccountSASSignatureValues sas = new AccountSASSignatureValues(); - AccountSASPermission perms = new AccountSASPermission(); - perms.read = true; - perms.write = true; - AccountSASService service = new AccountSASService(); - service.blob = true; - AccountSASResourceType resourceType = new AccountSASResourceType(); - resourceType.object = true; - sas.version = "2016-05-31"; - sas.protocol = SASProtocol.HTTPS_HTTP; - sas.startTime = null; - sas.expiryTime = OffsetDateTime.now().plusDays(1); - sas.permissions = perms.toString(); - sas.ipRange = null; - sas.services = service.toString(); - sas.resourceTypes = resourceType.toString(); - - // Construct a ServiceSASSignatureValues in a pattern similar to that of the AccountSASSignatureValues. - // Comment out the AccountSASSignatureValues creation and uncomment this to run with ServiceSASSignatureValues. - /*ServiceSASSignatureValues sas = new ServiceSASSignatureValues("2016-05-31", SASProtocol.HTTPS_HTTP, - DateTime.now().minusDays(1).toDate(), DateTime.now().plusDays(1).toDate(), - EnumSet.of(ContainerSASPermission.READ, ContainerSASPermission.WRITE), - null, containerName, null, null, - null, null, null, null);*/ - - - // generateSASQueryParameters hashes the sas using your account's credentials and then associates the - // sasQueryParameters with the blobURLParts. - parts.sasQueryParameters = sas.generateSASQueryParameters(creds); - - // Using a SAS requires AnonymousCredentials on the pipeline. - pipeline = StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions()); - - // Call toURL on the parts to get a string representation of the URL. This, along with the pipeline, - // is used to create a new BlockBlobURL object. - BlockBlobURL sasBlob = new BlockBlobURL(parts.toURL(), pipeline); - - // Download the blob using the SAS. To perform other operations, ensure the appropriate permissions are - // specified above. - data = sasBlob.download(new BlobRange(0L, 3L), null, false).blockingGet().body(); - dataByte = FlowableUtil.collectBytesInArray(data).blockingGet(); - assertArrayEquals(dataByte, new byte[]{0, 0, 0}); - - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } finally { - // Delete the blob and container. Deleting a container does not require deleting the blobs first. - // This is just for demonstration purposes. - try { - bu.delete(DeleteSnapshotsOptionType.INCLUDE, null).blockingGet(); - } finally { - cu.delete(null).blockingGet(); - } - } - } -} \ No newline at end of file diff --git a/src/test/java/com/microsoft/azure/storage/BlockBlobAPITest.groovy b/src/test/java/com/microsoft/azure/storage/BlockBlobAPITest.groovy index 7c7dcf1bcd8e..2814e3f54e62 100644 --- a/src/test/java/com/microsoft/azure/storage/BlockBlobAPITest.groovy +++ b/src/test/java/com/microsoft/azure/storage/BlockBlobAPITest.groovy @@ -15,18 +15,20 @@ package com.microsoft.azure.storage + +import com.microsoft.azure.storage.blob.models.* +import com.microsoft.rest.v2.http.UnexpectedLengthException import com.microsoft.azure.storage.blob.BlobAccessConditions -import com.microsoft.azure.storage.blob.BlobHTTPHeaders import com.microsoft.azure.storage.blob.BlobRange import com.microsoft.azure.storage.blob.BlockBlobURL -import com.microsoft.azure.storage.blob.HTTPAccessConditions -import com.microsoft.azure.storage.blob.LeaseAccessConditions import com.microsoft.azure.storage.blob.Metadata import com.microsoft.azure.storage.blob.StorageException import com.microsoft.azure.storage.blob.models.BlobGetPropertiesResponse import com.microsoft.azure.storage.blob.models.BlockBlobCommitBlockListHeaders import com.microsoft.azure.storage.blob.models.BlockBlobCommitBlockListResponse +import com.microsoft.azure.storage.blob.models.BlockBlobGetBlockListHeaders import com.microsoft.azure.storage.blob.models.BlockBlobGetBlockListResponse +import com.microsoft.azure.storage.blob.models.BlockBlobStageBlockFromURLHeaders import com.microsoft.azure.storage.blob.models.BlockBlobStageBlockHeaders import com.microsoft.azure.storage.blob.models.BlockBlobStageBlockResponse import com.microsoft.azure.storage.blob.models.BlockBlobUploadHeaders @@ -34,6 +36,7 @@ import com.microsoft.azure.storage.blob.models.BlockBlobUploadResponse import com.microsoft.azure.storage.blob.models.BlockListType import com.microsoft.azure.storage.blob.models.PublicAccessType import com.microsoft.azure.storage.blob.models.StorageErrorCode +import com.microsoft.rest.v2.http.HttpPipeline import com.microsoft.rest.v2.util.FlowableUtil import io.reactivex.Flowable import spock.lang.Unroll @@ -47,7 +50,7 @@ class BlockBlobAPITest extends APISpec { def setup() { bu = cu.createBlockBlobURL(generateBlobName()) bu.upload(defaultFlowable, defaultDataSize, null, null, - null).blockingGet() + null, null).blockingGet() } def getBlockID() { @@ -57,7 +60,7 @@ class BlockBlobAPITest extends APISpec { def "Stage block"() { setup: BlockBlobStageBlockResponse response = bu.stageBlock(getBlockID(), defaultFlowable, defaultDataSize, - null).blockingGet() + null, null).blockingGet() BlockBlobStageBlockHeaders headers = response.headers() expect: @@ -72,22 +75,23 @@ class BlockBlobAPITest extends APISpec { @Unroll def "Stage block illegal arguments"() { when: - bu.stageBlock(blockID, data, dataSize, null).blockingGet() + bu.stageBlock(blockID, data, dataSize, null, null).blockingGet() then: - thrown(IllegalArgumentException) + def e = thrown(Exception) + exceptionType.isInstance(e) where: - blockID | data | dataSize - null | defaultFlowable | defaultDataSize - getBlockID() | null | defaultDataSize - getBlockID() | defaultFlowable | defaultDataSize + 1 - getBlockID() | defaultFlowable | defaultDataSize - 1 + blockID | data | dataSize | exceptionType + null | defaultFlowable | defaultDataSize | IllegalArgumentException + getBlockID() | null | defaultDataSize | IllegalArgumentException + getBlockID() | defaultFlowable | defaultDataSize + 1 | UnexpectedLengthException + getBlockID() | defaultFlowable | defaultDataSize - 1 | UnexpectedLengthException } def "Stage block empty body"() { when: - bu.stageBlock(getBlockID(), Flowable.just(ByteBuffer.wrap(new byte[0])), 0, null) + bu.stageBlock(getBlockID(), Flowable.just(ByteBuffer.wrap(new byte[0])), 0, null, null) .blockingGet() then: @@ -96,7 +100,7 @@ class BlockBlobAPITest extends APISpec { def "Stage block null body"() { when: - bu.stageBlock(getBlockID(), Flowable.just(null), 0, null).blockingGet() + bu.stageBlock(getBlockID(), Flowable.just(null), 0, null, null).blockingGet() then: thrown(NullPointerException) // Thrown by Flowable.just(). @@ -107,8 +111,8 @@ class BlockBlobAPITest extends APISpec { String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) expect: - bu.stageBlock(getBlockID(), defaultFlowable, defaultDataSize, new LeaseAccessConditions(leaseID)) - .blockingGet().statusCode() == 201 + bu.stageBlock(getBlockID(), defaultFlowable, defaultDataSize, new LeaseAccessConditions().withLeaseId(leaseID), + null).blockingGet().statusCode() == 201 } def "Stage block lease fail"() { @@ -116,8 +120,8 @@ class BlockBlobAPITest extends APISpec { setupBlobLeaseCondition(bu, receivedLeaseID) when: - bu.stageBlock(getBlockID(), defaultFlowable, defaultDataSize, new LeaseAccessConditions(garbageLeaseID)) - .blockingGet() + bu.stageBlock(getBlockID(), defaultFlowable, defaultDataSize, new LeaseAccessConditions() + .withLeaseId(garbageLeaseID), null).blockingGet() then: def e = thrown(StorageException) @@ -129,24 +133,38 @@ class BlockBlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.stageBlock("id", defaultFlowable, defaultDataSize, null) + bu.stageBlock("id", defaultFlowable, defaultDataSize, null, null) .blockingGet() then: thrown(StorageException) } + def "Stage block context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, BlockBlobStageBlockHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.stageBlock("id", defaultFlowable, defaultDataSize, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Stage block from url"() { setup: - cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null).blockingGet() + cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null, null).blockingGet() def bu2 = cu.createBlockBlobURL(generateBlobName()) def blockID = getBlockID() when: def response = bu2.stageBlockFromURL(blockID, bu.toURL(), null, null, - null).blockingGet() - def listResponse = bu2.getBlockList(BlockListType.ALL, null).blockingGet() - bu2.commitBlockList(Arrays.asList(blockID), null, null, null).blockingGet() + null, null).blockingGet() + def listResponse = bu2.getBlockList(BlockListType.ALL, null, null).blockingGet() + bu2.commitBlockList(Arrays.asList(blockID), null, null, null, null).blockingGet() then: response.headers().requestId() != null @@ -158,48 +176,47 @@ class BlockBlobAPITest extends APISpec { listResponse.body().uncommittedBlocks().get(0).name() == blockID listResponse.body().uncommittedBlocks().size() == 1 - FlowableUtil.collectBytesInBuffer(bu2.download(null, null, false) - .blockingGet().body()).blockingGet() == defaultData + FlowableUtil.collectBytesInBuffer(bu2.download(null, null, false, null) + .blockingGet().body(null)).blockingGet() == defaultData } @Unroll def "Stage block from URL IA"() { when: - bu.stageBlockFromURL(blockID, sourceURL, null, null, null) + bu.stageBlockFromURL(blockID, sourceURL, null, null, null, null) .blockingGet() then: thrown(IllegalArgumentException) where: - blockID | sourceURL - null | new URL("http://www.example.com") + blockID | sourceURL + null | new URL("http://www.example.com") getBlockID() | null } def "Stage block from URL range"() { setup: - cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null).blockingGet() + cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null, null).blockingGet() def destURL = cu.createBlockBlobURL(generateBlobName()) when: - destURL.stageBlockFromURL(getBlockID(), bu.toURL(), new BlobRange(2, 3), null, + destURL.stageBlockFromURL(getBlockID(), bu.toURL(), new BlobRange().withOffset(2).withCount(3), null, null, null).blockingGet() then: - destURL.getBlockList(BlockListType.ALL, null).blockingGet().body().uncommittedBlocks().get(0) + destURL.getBlockList(BlockListType.ALL, null, null).blockingGet().body().uncommittedBlocks().get(0) .size() == 3 } def "Stage block from URL MD5"() { setup: - cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null).blockingGet() + cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null, null).blockingGet() def destURL = cu.createBlockBlobURL(generateBlobName()) when: destURL.stageBlockFromURL(getBlockID(), bu.toURL(), null, - MessageDigest.getInstance("MD5").digest(defaultData.array()),null) - .blockingGet() + MessageDigest.getInstance("MD5").digest(defaultData.array()), null, null).blockingGet() then: notThrown(StorageException) @@ -207,12 +224,12 @@ class BlockBlobAPITest extends APISpec { def "Stage block from URL MD5 fail"() { setup: - cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null).blockingGet() + cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null, null).blockingGet() def destURL = cu.createBlockBlobURL(generateBlobName()) when: destURL.stageBlockFromURL(getBlockID(), bu.toURL(), null, "garbage".getBytes(), - null).blockingGet() + null, null).blockingGet() then: thrown(StorageException) @@ -220,11 +237,11 @@ class BlockBlobAPITest extends APISpec { def "Stage block from URL lease"() { setup: - cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null).blockingGet() - def lease = new LeaseAccessConditions(setupBlobLeaseCondition(bu, receivedLeaseID)) + cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null, null).blockingGet() + def lease = new LeaseAccessConditions().withLeaseId(setupBlobLeaseCondition(bu, receivedLeaseID)) when: - bu.stageBlockFromURL(getBlockID(), bu.toURL(), null, null, lease).blockingGet() + bu.stageBlockFromURL(getBlockID(), bu.toURL(), null, null, lease, null).blockingGet() then: notThrown(StorageException) @@ -232,11 +249,11 @@ class BlockBlobAPITest extends APISpec { def "Stage block from URL lease fail"() { setup: - cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null).blockingGet() - def lease = new LeaseAccessConditions("garbage") + cu.setAccessPolicy(PublicAccessType.CONTAINER, null, null, null).blockingGet() + def lease = new LeaseAccessConditions().withLeaseId("garbage") when: - bu.stageBlockFromURL(getBlockID(), bu.toURL(), null, null, lease).blockingGet() + bu.stageBlockFromURL(getBlockID(), bu.toURL(), null, null, lease, null).blockingGet() then: thrown(StorageException) @@ -248,24 +265,38 @@ class BlockBlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.stageBlockFromURL(getBlockID(), bu.toURL(), null, null, null) + bu.stageBlockFromURL(getBlockID(), bu.toURL(), null, null, null, null) .blockingGet() then: thrown(StorageException) } + def "Stage block from URL context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, BlockBlobStageBlockFromURLHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.stageBlockFromURL("id", bu.toURL(), null, null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Commit block list"() { setup: String blockID = getBlockID() bu.stageBlock(blockID, defaultFlowable, defaultDataSize, - null).blockingGet() + null, null).blockingGet() ArrayList ids = new ArrayList<>() ids.add(blockID) when: BlockBlobCommitBlockListResponse response = - bu.commitBlockList(ids, null, null, null).blockingGet() + bu.commitBlockList(ids, null, null, null, null).blockingGet() BlockBlobCommitBlockListHeaders headers = response.headers() then: @@ -277,7 +308,7 @@ class BlockBlobAPITest extends APISpec { def "Commit block list null"() { expect: - bu.commitBlockList(null, null, null, null) + bu.commitBlockList(null, null, null, null, null) .blockingGet().statusCode() == 201 } @@ -286,15 +317,19 @@ class BlockBlobAPITest extends APISpec { setup: String blockID = getBlockID() bu.stageBlock(blockID, defaultFlowable, defaultDataSize, - null).blockingGet() + null, null).blockingGet() ArrayList ids = new ArrayList<>() ids.add(blockID) - BlobHTTPHeaders headers = new BlobHTTPHeaders(cacheControl, contentDisposition, contentEncoding, - contentLanguage, contentMD5, contentType) + BlobHTTPHeaders headers = new BlobHTTPHeaders().withBlobCacheControl(cacheControl) + .withBlobContentDisposition(contentDisposition) + .withBlobContentEncoding(contentEncoding) + .withBlobContentLanguage(contentLanguage) + .withBlobContentMD5(contentMD5) + .withBlobContentType(contentType) when: - bu.commitBlockList(ids, headers, null, null).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + bu.commitBlockList(ids, headers, null, null, null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: response.statusCode() == 200 @@ -320,8 +355,8 @@ class BlockBlobAPITest extends APISpec { } when: - bu.commitBlockList(null, null, metadata, null).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + bu.commitBlockList(null, null, metadata, null, null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: response.statusCode() == 200 @@ -338,12 +373,13 @@ class BlockBlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - bu.commitBlockList(null, null, null, bac).blockingGet().statusCode() == 201 + bu.commitBlockList(null, null, null, bac, null).blockingGet().statusCode() == 201 where: modified | unmodified | match | noneMatch | leaseID @@ -360,12 +396,13 @@ class BlockBlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.commitBlockList(null, null, null, bac).blockingGet() + bu.commitBlockList(null, null, null, bac, null).blockingGet() then: def e = thrown(StorageException) @@ -386,24 +423,37 @@ class BlockBlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.commitBlockList(new ArrayList(), null, null, new BlobAccessConditions( - null, new LeaseAccessConditions("garbage"), null, - null)).blockingGet() + bu.commitBlockList(new ArrayList(), null, null, new BlobAccessConditions().withLeaseAccessConditions( + new LeaseAccessConditions().withLeaseId("garbage")), null).blockingGet() then: thrown(StorageException) } + def "Commit block list info context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, BlockBlobCommitBlockListHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.commitBlockList(new ArrayList(), null, null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Get block list"() { setup: String blockID = getBlockID() - bu.stageBlock(blockID, defaultFlowable, defaultDataSize,null).blockingGet() - bu.commitBlockList(Arrays.asList(blockID), null, null, null).blockingGet() + bu.stageBlock(blockID, defaultFlowable, defaultDataSize, null, null).blockingGet() + bu.commitBlockList(Arrays.asList(blockID), null, null, null, null).blockingGet() String blockID2 = getBlockID() - bu.stageBlock(blockID2, defaultFlowable, defaultDataSize, null).blockingGet() + bu.stageBlock(blockID2, defaultFlowable, defaultDataSize, null, null).blockingGet() when: - BlockBlobGetBlockListResponse response = bu.getBlockList(BlockListType.ALL, null) + BlockBlobGetBlockListResponse response = bu.getBlockList(BlockListType.ALL, null, null) .blockingGet() then: @@ -423,16 +473,16 @@ class BlockBlobAPITest extends APISpec { setup: String blockID = getBlockID() bu.stageBlock(blockID, defaultFlowable, defaultDataSize, - null).blockingGet() + null, null).blockingGet() ArrayList ids = new ArrayList<>() ids.add(blockID) - bu.commitBlockList(ids, null, null, null).blockingGet() + bu.commitBlockList(ids, null, null, null, null).blockingGet() blockID = new String(getBlockID()) bu.stageBlock(blockID, defaultFlowable, defaultDataSize, - null).blockingGet() + null, null).blockingGet() when: - BlockBlobGetBlockListResponse response = bu.getBlockList(type, null).blockingGet() + BlockBlobGetBlockListResponse response = bu.getBlockList(type, null, null).blockingGet() then: response.body().committedBlocks().size() == committedCount @@ -447,7 +497,7 @@ class BlockBlobAPITest extends APISpec { def "Get block list type null"() { when: - bu.getBlockList(null, null).blockingGet() + bu.getBlockList(null, null, null).blockingGet() then: thrown(IllegalArgumentException) @@ -458,7 +508,8 @@ class BlockBlobAPITest extends APISpec { String leaseID = setupBlobLeaseCondition(bu, receivedLeaseID) expect: - bu.getBlockList(BlockListType.ALL, new LeaseAccessConditions(leaseID)).blockingGet().statusCode() == 200 + bu.getBlockList(BlockListType.ALL, new LeaseAccessConditions().withLeaseId(leaseID), null) + .blockingGet().statusCode() == 200 } def "Get block list lease fail"() { @@ -466,7 +517,7 @@ class BlockBlobAPITest extends APISpec { setupBlobLeaseCondition(bu, garbageLeaseID) when: - bu.getBlockList(BlockListType.ALL, new LeaseAccessConditions(garbageLeaseID)).blockingGet() + bu.getBlockList(BlockListType.ALL, new LeaseAccessConditions().withLeaseId(garbageLeaseID), null).blockingGet() then: def e = thrown(StorageException) @@ -478,22 +529,36 @@ class BlockBlobAPITest extends APISpec { bu = cu.createBlockBlobURL(generateBlobName()) when: - bu.getBlockList(BlockListType.ALL, null).blockingGet() + bu.getBlockList(BlockListType.ALL, null, null).blockingGet() then: thrown(StorageException) } + def "Get block list context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, BlockBlobGetBlockListHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.getBlockList(BlockListType.ALL, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Upload"() { when: BlockBlobUploadResponse response = bu.upload(defaultFlowable, defaultDataSize, - null, null, null).blockingGet() + null, null, null, null).blockingGet() BlockBlobUploadHeaders headers = response.headers() then: response.statusCode() == 201 FlowableUtil.collectBytesInBuffer( - bu.download(null, null, false).blockingGet().body()) + bu.download(null, null, false, null).blockingGet().body(null)) .blockingGet() == defaultData validateBasicHeaders(headers) headers.contentMD5() != null @@ -503,27 +568,28 @@ class BlockBlobAPITest extends APISpec { @Unroll def "Upload illegal argument"() { when: - bu.upload(data, dataSize, null, null, null).blockingGet() + bu.upload(data, dataSize, null, null, null, null).blockingGet() then: - thrown(IllegalArgumentException) + def e = thrown(Exception) + exceptionType.isInstance(e) where: - data | dataSize - null | defaultDataSize - defaultFlowable | defaultDataSize + 1 - defaultFlowable | defaultDataSize - 1 + data | dataSize | exceptionType + null | defaultDataSize | IllegalArgumentException + defaultFlowable | defaultDataSize + 1 | UnexpectedLengthException + defaultFlowable | defaultDataSize - 1 | UnexpectedLengthException } def "Upload empty body"() { expect: bu.upload(Flowable.just(ByteBuffer.wrap(new byte[0])), 0, null, null, - null).blockingGet().statusCode() == 201 + null, null).blockingGet().statusCode() == 201 } def "Upload null body"() { when: - bu.upload(Flowable.just(null), 0, null, null, null).blockingGet() + bu.upload(Flowable.just(null), 0, null, null, null, null).blockingGet() then: thrown(NullPointerException) // Thrown by Flowable.just(). @@ -532,13 +598,17 @@ class BlockBlobAPITest extends APISpec { @Unroll def "Upload headers"() { setup: - BlobHTTPHeaders headers = new BlobHTTPHeaders(cacheControl, contentDisposition, contentEncoding, - contentLanguage, contentMD5, contentType) + BlobHTTPHeaders headers = new BlobHTTPHeaders().withBlobCacheControl(cacheControl) + .withBlobContentDisposition(contentDisposition) + .withBlobContentEncoding(contentEncoding) + .withBlobContentLanguage(contentLanguage) + .withBlobContentMD5(contentMD5) + .withBlobContentType(contentType) when: bu.upload(defaultFlowable, defaultDataSize, - headers, null, null).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + headers, null, null, null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: validateBlobHeaders(response.headers(), cacheControl, contentDisposition, contentEncoding, contentLanguage, @@ -566,8 +636,8 @@ class BlockBlobAPITest extends APISpec { when: bu.upload(defaultFlowable, defaultDataSize, - null, metadata, null).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + null, metadata, null, null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: response.statusCode() == 200 @@ -584,13 +654,14 @@ class BlockBlobAPITest extends APISpec { setup: match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: bu.upload(defaultFlowable, defaultDataSize, - null, null, bac).blockingGet().statusCode() == 201 + null, null, bac, null).blockingGet().statusCode() == 201 where: modified | unmodified | match | noneMatch | leaseID @@ -607,12 +678,13 @@ class BlockBlobAPITest extends APISpec { setup: noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - bu.upload(defaultFlowable, defaultDataSize, null, null, bac).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, bac, null).blockingGet() then: def e = thrown(StorageException) @@ -634,10 +706,24 @@ class BlockBlobAPITest extends APISpec { when: bu.upload(defaultFlowable, defaultDataSize, null, null, - new BlobAccessConditions(null, new LeaseAccessConditions("id"), - null, null)).blockingGet() + new BlobAccessConditions().withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId("id")), + null).blockingGet() then: thrown(StorageException) } + + def "Upload context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, BlockBlobUploadHeaders))) + + bu = bu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + bu.upload(defaultFlowable, defaultDataSize, null, null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } } diff --git a/src/test/java/com/microsoft/azure/storage/ContainerAPITest.groovy b/src/test/java/com/microsoft/azure/storage/ContainerAPITest.groovy index 7b585f34a8ff..33e348a1fff4 100644 --- a/src/test/java/com/microsoft/azure/storage/ContainerAPITest.groovy +++ b/src/test/java/com/microsoft/azure/storage/ContainerAPITest.groovy @@ -22,8 +22,7 @@ import com.microsoft.azure.storage.blob.BlobListingDetails import com.microsoft.azure.storage.blob.BlockBlobURL import com.microsoft.azure.storage.blob.ContainerAccessConditions import com.microsoft.azure.storage.blob.ContainerURL -import com.microsoft.azure.storage.blob.HTTPAccessConditions -import com.microsoft.azure.storage.blob.LeaseAccessConditions + import com.microsoft.azure.storage.blob.ListBlobsOptions import com.microsoft.azure.storage.blob.Metadata import com.microsoft.azure.storage.blob.PageBlobURL @@ -40,9 +39,13 @@ import com.microsoft.azure.storage.blob.models.BlobType import com.microsoft.azure.storage.blob.models.ContainerAcquireLeaseHeaders import com.microsoft.azure.storage.blob.models.ContainerBreakLeaseHeaders import com.microsoft.azure.storage.blob.models.ContainerChangeLeaseHeaders +import com.microsoft.azure.storage.blob.models.ContainerCreateHeaders import com.microsoft.azure.storage.blob.models.ContainerCreateResponse +import com.microsoft.azure.storage.blob.models.ContainerDeleteHeaders import com.microsoft.azure.storage.blob.models.ContainerDeleteResponse +import com.microsoft.azure.storage.blob.models.ContainerGetAccessPolicyHeaders import com.microsoft.azure.storage.blob.models.ContainerGetAccessPolicyResponse +import com.microsoft.azure.storage.blob.models.ContainerGetAccountInfoHeaders import com.microsoft.azure.storage.blob.models.ContainerGetPropertiesHeaders import com.microsoft.azure.storage.blob.models.ContainerGetPropertiesResponse import com.microsoft.azure.storage.blob.models.ContainerListBlobFlatSegmentHeaders @@ -51,12 +54,16 @@ import com.microsoft.azure.storage.blob.models.ContainerListBlobHierarchySegment import com.microsoft.azure.storage.blob.models.ContainerListBlobHierarchySegmentResponse import com.microsoft.azure.storage.blob.models.ContainerReleaseLeaseHeaders import com.microsoft.azure.storage.blob.models.ContainerRenewLeaseHeaders +import com.microsoft.azure.storage.blob.models.ContainerSetAccessPolicyHeaders import com.microsoft.azure.storage.blob.models.ContainerSetAccessPolicyResponse +import com.microsoft.azure.storage.blob.models.ContainerSetMetadataHeaders import com.microsoft.azure.storage.blob.models.ContainerSetMetadataResponse import com.microsoft.azure.storage.blob.models.CopyStatusType +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions import com.microsoft.azure.storage.blob.models.LeaseDurationType import com.microsoft.azure.storage.blob.models.LeaseStateType import com.microsoft.azure.storage.blob.models.LeaseStatusType +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions import com.microsoft.azure.storage.blob.models.PublicAccessType import com.microsoft.azure.storage.blob.models.SignedIdentifier import com.microsoft.azure.storage.blob.models.StorageErrorCode @@ -82,7 +89,7 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - ContainerCreateResponse response = cu.create(null, null).blockingGet() + ContainerCreateResponse response = cu.create(null, null, null).blockingGet() then: response.statusCode() == 201 @@ -102,8 +109,8 @@ class ContainerAPITest extends APISpec { } when: - cu.create(metadata, null).blockingGet() - ContainerGetPropertiesResponse response = cu.getProperties(null).blockingGet() + cu.create(metadata, null, null).blockingGet() + ContainerGetPropertiesResponse response = cu.getProperties(null, null).blockingGet() then: response.headers().metadata() == metadata @@ -120,9 +127,9 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.create(null, publicAccess).blockingGet() + cu.create(null, publicAccess, null).blockingGet() PublicAccessType access = - cu.getProperties(null).blockingGet().headers().blobPublicAccess() + cu.getProperties(null, null).blockingGet().headers().blobPublicAccess() then: access.toString() == publicAccess.toString() @@ -134,9 +141,9 @@ class ContainerAPITest extends APISpec { null | _ } - def "Create exception"() { + def "Create error"() { when: - cu.create(null, null).blockingGet() + cu.create(null, null, null).blockingGet() then: def e = thrown(StorageException) @@ -145,10 +152,24 @@ class ContainerAPITest extends APISpec { e.message().contains("The specified container already exists.") } + def "Create context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(201, ContainerCreateHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.create(null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Get properties null"() { when: ContainerGetPropertiesHeaders headers = - cu.getProperties(null).blockingGet().headers() + cu.getProperties(null, null).blockingGet().headers() then: validateBasicHeaders(headers) @@ -166,12 +187,12 @@ class ContainerAPITest extends APISpec { String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) expect: - cu.getProperties(new LeaseAccessConditions(leaseID)).blockingGet().statusCode() == 200 + cu.getProperties(new LeaseAccessConditions().withLeaseId(leaseID), null).blockingGet().statusCode() == 200 } def "Get properties lease fail"() { when: - cu.getProperties(new LeaseAccessConditions("garbage")).blockingGet() + cu.getProperties(new LeaseAccessConditions().withLeaseId("garbage"), null).blockingGet() then: thrown(StorageException) @@ -182,24 +203,38 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.getProperties(null).blockingGet() + cu.getProperties(null, null).blockingGet() then: thrown(StorageException) } + def "Get properties context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerGetPropertiesHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.getProperties(null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Set metadata"() { setup: cu = primaryServiceURL.createContainerURL(generateContainerName()) Metadata metadata = new Metadata() metadata.put("key", "value") - cu.create(metadata, null).blockingGet() - ContainerSetMetadataResponse response = cu.setMetadata(null, null).blockingGet() + cu.create(metadata, null, null).blockingGet() + ContainerSetMetadataResponse response = cu.setMetadata(null, null, null).blockingGet() expect: response.statusCode() == 200 validateBasicHeaders(response.headers()) - cu.getProperties(null).blockingGet().headers().metadata().size() == 0 + cu.getProperties(null, null).blockingGet().headers().metadata().size() == 0 } @Unroll @@ -214,8 +249,8 @@ class ContainerAPITest extends APISpec { } expect: - cu.setMetadata(metadata, null).blockingGet().statusCode() == 200 - cu.getProperties(null).blockingGet().headers().metadata() == metadata + cu.setMetadata(metadata, null, null).blockingGet().statusCode() == 200 + cu.getProperties(null, null).blockingGet().headers().metadata() == metadata where: key1 | value1 | key2 | value2 @@ -228,12 +263,12 @@ class ContainerAPITest extends APISpec { def "Set metadata AC"() { setup: leaseID = setupContainerLeaseCondition(cu, leaseID) - ContainerAccessConditions cac = new ContainerAccessConditions( - new HTTPAccessConditions(modified, null, null, null), - new LeaseAccessConditions(leaseID)) + ContainerAccessConditions cac = new ContainerAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - cu.setMetadata(null, cac).blockingGet().statusCode() == 200 + cu.setMetadata(null, cac, null).blockingGet().statusCode() == 200 where: modified | leaseID @@ -245,12 +280,12 @@ class ContainerAPITest extends APISpec { @Unroll def "Set metadata AC fail"() { setup: - ContainerAccessConditions cac = new ContainerAccessConditions( - new HTTPAccessConditions(modified, null, null, null), - new LeaseAccessConditions(leaseID)) + ContainerAccessConditions cac = new ContainerAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - cu.setMetadata(null, cac).blockingGet() + cu.setMetadata(null, cac, null).blockingGet() then: thrown(StorageException) @@ -264,10 +299,11 @@ class ContainerAPITest extends APISpec { @Unroll def "Set metadata AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, unmodified, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.setMetadata(null, new ContainerAccessConditions(hac, null)) + cu.setMetadata(null, new ContainerAccessConditions().withModifiedAccessConditions(mac), null) then: thrown(IllegalArgumentException) @@ -284,20 +320,34 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.setMetadata(null, null).blockingGet() + cu.setMetadata(null, null, null).blockingGet() then: thrown(StorageException) } + def "Set metadata context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerSetMetadataHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.setMetadata(null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + @Unroll def "Set access policy"() { setup: - def response = cu.setAccessPolicy(access, null, null).blockingGet() + def response = cu.setAccessPolicy(access, null, null, null).blockingGet() expect: validateBasicHeaders(response.headers()) - cu.getProperties(null).blockingGet() + cu.getProperties(null, null).blockingGet() .headers().blobPublicAccess() == access where: @@ -329,8 +379,8 @@ class ContainerAPITest extends APISpec { when: ContainerSetAccessPolicyResponse response = - cu.setAccessPolicy(null, ids, null).blockingGet() - List receivedIdentifiers = cu.getAccessPolicy(null).blockingGet().body() + cu.setAccessPolicy(null, ids, null, null).blockingGet() + List receivedIdentifiers = cu.getAccessPolicy(null, null).blockingGet().body() then: response.statusCode() == 200 @@ -347,12 +397,12 @@ class ContainerAPITest extends APISpec { def "Set access policy AC"() { setup: leaseID = setupContainerLeaseCondition(cu, leaseID) - ContainerAccessConditions cac = new ContainerAccessConditions( - new HTTPAccessConditions(modified, unmodified, null, null), - new LeaseAccessConditions(leaseID)) + ContainerAccessConditions cac = new ContainerAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) expect: - cu.setAccessPolicy(null, null, cac).blockingGet().statusCode() == 200 + cu.setAccessPolicy(null, null, cac, null).blockingGet().statusCode() == 200 where: modified | unmodified | leaseID @@ -365,12 +415,12 @@ class ContainerAPITest extends APISpec { @Unroll def "Set access policy AC fail"() { setup: - ContainerAccessConditions cac = new ContainerAccessConditions( - new HTTPAccessConditions(modified, unmodified, null, null), - new LeaseAccessConditions(leaseID)) + ContainerAccessConditions cac = new ContainerAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - cu.setAccessPolicy(null, null, cac).blockingGet() + cu.setAccessPolicy(null, null, cac, null).blockingGet() then: thrown(StorageException) @@ -385,10 +435,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Set access policy AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, null, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.setAccessPolicy(null, null, new ContainerAccessConditions(hac, null)) + cu.setAccessPolicy(null, null, new ContainerAccessConditions().withModifiedAccessConditions(mac), null) then: thrown(IllegalArgumentException) @@ -404,12 +454,26 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.setAccessPolicy(null, null, null).blockingGet() + cu.setAccessPolicy(null, null, null, null).blockingGet() then: thrown(StorageException) } + def "Set access policy context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerSetAccessPolicyHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.setAccessPolicy(null, null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Get access policy"() { setup: SignedIdentifier identifier = new SignedIdentifier() @@ -421,8 +485,8 @@ class ContainerAPITest extends APISpec { .withPermission("r")) List ids = new ArrayList<>() ids.push(identifier) - cu.setAccessPolicy(PublicAccessType.BLOB, ids, null).blockingGet() - ContainerGetAccessPolicyResponse response = cu.getAccessPolicy(null).blockingGet() + cu.setAccessPolicy(PublicAccessType.BLOB, ids, null, null).blockingGet() + ContainerGetAccessPolicyResponse response = cu.getAccessPolicy(null, null).blockingGet() expect: response.statusCode() == 200 @@ -438,12 +502,12 @@ class ContainerAPITest extends APISpec { String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) expect: - cu.getAccessPolicy(new LeaseAccessConditions(leaseID)).blockingGet().statusCode() == 200 + cu.getAccessPolicy(new LeaseAccessConditions().withLeaseId(leaseID), null).blockingGet().statusCode() == 200 } def "Get access policy lease fail"() { when: - cu.getAccessPolicy(new LeaseAccessConditions(garbageLeaseID)).blockingGet() + cu.getAccessPolicy(new LeaseAccessConditions().withLeaseId(garbageLeaseID), null).blockingGet() then: thrown(StorageException) @@ -454,15 +518,29 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.getAccessPolicy(null).blockingGet() + cu.getAccessPolicy(null, null).blockingGet() then: thrown(StorageException) } + def "Get access policy context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerGetAccessPolicyHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.getAccessPolicy(null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Delete"() { when: - ContainerDeleteResponse response = cu.delete(null).blockingGet() + ContainerDeleteResponse response = cu.delete(null, null).blockingGet() then: response.statusCode() == 202 @@ -475,12 +553,13 @@ class ContainerAPITest extends APISpec { def "Delete AC"() { setup: leaseID = setupContainerLeaseCondition(cu, leaseID) - ContainerAccessConditions cac = new ContainerAccessConditions( - new HTTPAccessConditions(modified, unmodified, null, null), - new LeaseAccessConditions(leaseID)) + ContainerAccessConditions cac = new ContainerAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) + expect: - cu.delete(cac).blockingGet().statusCode() == 202 + cu.delete(cac, null).blockingGet().statusCode() == 202 where: modified | unmodified | leaseID @@ -493,12 +572,12 @@ class ContainerAPITest extends APISpec { @Unroll def "Delete AC fail"() { setup: - ContainerAccessConditions cac = new ContainerAccessConditions( - new HTTPAccessConditions(modified, unmodified, null, null), - new LeaseAccessConditions(leaseID)) + ContainerAccessConditions cac = new ContainerAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - cu.delete(cac).blockingGet() + cu.delete(cac, null).blockingGet() then: thrown(StorageException) @@ -513,10 +592,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Delete AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, null, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.delete(new ContainerAccessConditions(hac, null)) + cu.delete(new ContainerAccessConditions().withModifiedAccessConditions(mac), null) then: thrown(IllegalArgumentException) @@ -532,20 +611,34 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.delete(null).blockingGet() + cu.delete(null, null).blockingGet() then: thrown(StorageException) } + def "Delete context"() { + setup: + def pipeline = HttpPipeline.build(getStubFactory(getContextStubPolicy(202, ContainerDeleteHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.delete(null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "List blobs flat"() { setup: String name = generateBlobName() PageBlobURL bu = cu.createPageBlobURL(name) - bu.create(512, null, null, null, null).blockingGet() + bu.create(512, null, null, null, null, null).blockingGet() when: - ContainerListBlobFlatSegmentResponse response = cu.listBlobsFlatSegment(null, null) + ContainerListBlobFlatSegmentResponse response = cu.listBlobsFlatSegment(null, null, null) .blockingGet() ContainerListBlobFlatSegmentHeaders headers = response.headers() List blobs = response.body().segment().blobItems() @@ -587,33 +680,31 @@ class ContainerAPITest extends APISpec { def setupListBlobsTest(String normalName, String copyName, String metadataName, String uncommittedName) { PageBlobURL normal = cu.createPageBlobURL(normalName) - normal.create(512, null, null, null, null).blockingGet() + normal.create(512, null, null, null, null, null).blockingGet() PageBlobURL copyBlob = cu.createPageBlobURL(copyName) waitForCopy(copyBlob, copyBlob.startCopyFromURL(normal.toURL(), - null, null, null).blockingGet()) + null, null, null, null).blockingGet().headers().copyStatus()) PageBlobURL metadataBlob = cu.createPageBlobURL(metadataName) Metadata values = new Metadata() values.put("foo", "bar") - metadataBlob.create(512, null, null, values, null).blockingGet() + metadataBlob.create(512, null, null, values, null, null).blockingGet() - String snapshotTime = normal.createSnapshot(null, null) + String snapshotTime = normal.createSnapshot(null, null, null) .blockingGet().headers().snapshot() BlockBlobURL uncommittedBlob = cu.createBlockBlobURL(uncommittedName) uncommittedBlob.stageBlock("0000", Flowable.just(defaultData), defaultData.remaining(), - null).blockingGet() + null, null).blockingGet() return snapshotTime } def "List blobs flat options copy"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - true, false, false, false, false), - null, null) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails().withCopy(true)) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -621,7 +712,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsFlatSegment(null, options).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsFlatSegment(null, options, null).blockingGet().body().segment().blobItems() then: blobs.get(0).name() == normalName @@ -637,9 +728,7 @@ class ContainerAPITest extends APISpec { def "List blobs flat options metadata"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - false, true, false, false, false), - null, null) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails().withMetadata(true)) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -647,7 +736,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsFlatSegment(null, options).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsFlatSegment(null, options, null).blockingGet().body().segment().blobItems() then: blobs.get(0).name() == normalName @@ -660,9 +749,7 @@ class ContainerAPITest extends APISpec { def "List blobs flat options snapshots"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - false, false, true, false, false), - null, null) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails().withSnapshots(true)) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -670,7 +757,7 @@ class ContainerAPITest extends APISpec { String snapshotTime = setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsFlatSegment(null, options).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsFlatSegment(null, options, null).blockingGet().body().segment().blobItems() then: blobs.get(0).name() == normalName @@ -681,9 +768,8 @@ class ContainerAPITest extends APISpec { def "List blobs flat options uncommitted"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - false, false, false, true, false), - null, null) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails() + .withUncommittedBlobs(true)) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -691,7 +777,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsFlatSegment(null, options).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsFlatSegment(null, options, null).blockingGet().body().segment().blobItems() then: blobs.get(0).name() == normalName @@ -704,13 +790,12 @@ class ContainerAPITest extends APISpec { enableSoftDelete() String name = generateBlobName() AppendBlobURL bu = cu.createAppendBlobURL(name) - bu.create(null, null, null).blockingGet() - bu.delete(null, null).blockingGet() + bu.create(null, null, null, null).blockingGet() + bu.delete(null, null, null).blockingGet() when: - List blobs = cu.listBlobsFlatSegment(null, new ListBlobsOptions(new BlobListingDetails( - false, false, false, false, true), null, - null)).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsFlatSegment(null, new ListBlobsOptions().withDetails(new BlobListingDetails() + .withDeletedBlobs(true)), null).blockingGet().body().segment().blobItems() then: blobs.get(0).name() == name @@ -721,7 +806,7 @@ class ContainerAPITest extends APISpec { def "List blobs flat options prefix"() { setup: - ListBlobsOptions options = new ListBlobsOptions(null, "a", null) + ListBlobsOptions options = new ListBlobsOptions().withPrefix("a") String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -729,7 +814,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsFlatSegment(null, options).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsFlatSegment(null, options, null).blockingGet().body().segment().blobItems() then: blobs.get(0).name() == normalName @@ -738,9 +823,8 @@ class ContainerAPITest extends APISpec { def "List blobs flat options maxResults"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - true, false, true, true, false), - null, 2) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails().withCopy(true) + .withSnapshots(true).withUncommittedBlobs(true)).withMaxResults(2) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -748,7 +832,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsFlatSegment(null, options).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsFlatSegment(null, options, null).blockingGet().body().segment().blobItems() then: blobs.size() == 2 @@ -756,7 +840,7 @@ class ContainerAPITest extends APISpec { def "List blobs flat options fail"() { when: - new ListBlobsOptions(null, null, 0) + new ListBlobsOptions().withMaxResults(0) then: thrown(IllegalArgumentException) @@ -766,15 +850,15 @@ class ContainerAPITest extends APISpec { setup: for (int i = 0; i < 10; i++) { PageBlobURL bu = cu.createPageBlobURL(generateBlobName()) - bu.create(512, null, null, null, null).blockingGet() + bu.create(512, null, null, null, null, null).blockingGet() } ContainerListBlobFlatSegmentResponse response = cu.listBlobsFlatSegment(null, - new ListBlobsOptions(null, null, 6)) + new ListBlobsOptions().withMaxResults(6), null) .blockingGet() String marker = response.body().nextMarker() int firstSegmentSize = response.body().segment().blobItems().size() - response = cu.listBlobsFlatSegment(marker, null).blockingGet() + response = cu.listBlobsFlatSegment(marker, null, null).blockingGet() expect: firstSegmentSize == 6 @@ -787,21 +871,36 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.listBlobsFlatSegment(null, null).blockingGet() + cu.listBlobsFlatSegment(null, null, null).blockingGet() then: thrown(StorageException) } + def "List blobs flat context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerListBlobFlatSegmentHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.listBlobsFlatSegment(null, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "List blobs hierarchy"() { setup: String name = generateBlobName() PageBlobURL bu = cu.createPageBlobURL(name) - bu.create(512, null, null, null, null).blockingGet() + bu.create(512, null, null, null, null, null).blockingGet() when: ContainerListBlobHierarchySegmentResponse response = - cu.listBlobsHierarchySegment(null, "/", null) + cu.listBlobsHierarchySegment(null, "/", null, null) .blockingGet() ContainerListBlobHierarchySegmentHeaders headers = response.headers() List blobs = response.body().segment().blobItems() @@ -818,9 +917,7 @@ class ContainerAPITest extends APISpec { def "List blobs hier options copy"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - true, false, false, false, false), - null, null) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails().withCopy(true)) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -828,7 +925,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsHierarchySegment(null, "", options).blockingGet().body().segment().blobItems() + List blobs = cu.listBlobsHierarchySegment(null, "", options, null).blockingGet().body().segment().blobItems() then: blobs.get(0).name() == normalName @@ -844,9 +941,7 @@ class ContainerAPITest extends APISpec { def "List blobs hier options metadata"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - false, true, false, false, false), - null, null) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails().withMetadata(true)) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -854,7 +949,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsHierarchySegment(null, "", options) + List blobs = cu.listBlobsHierarchySegment(null, "", options, null) .blockingGet().body().segment().blobItems() then: @@ -868,9 +963,8 @@ class ContainerAPITest extends APISpec { def "List blobs hier options uncommitted"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - false, false, false, true, false), - null, null) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails() + .withUncommittedBlobs(true)) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -878,7 +972,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsHierarchySegment(null, "", options) + List blobs = cu.listBlobsHierarchySegment(null, "", options, null) .blockingGet().body().segment().blobItems() then: @@ -892,13 +986,12 @@ class ContainerAPITest extends APISpec { enableSoftDelete() String name = generateBlobName() AppendBlobURL bu = cu.createAppendBlobURL(name) - bu.create(null, null, null).blockingGet() - bu.delete(null, null).blockingGet() + bu.create(null, null, null, null).blockingGet() + bu.delete(null, null, null).blockingGet() when: List blobs = cu.listBlobsHierarchySegment(null, "", - new ListBlobsOptions(new BlobListingDetails(false, false, false, - false, true), null, null)).blockingGet() + new ListBlobsOptions().withDetails(new BlobListingDetails().withDeletedBlobs(true)), null).blockingGet() .body().segment().blobItems() then: @@ -910,7 +1003,7 @@ class ContainerAPITest extends APISpec { def "List blobs hier options prefix"() { setup: - ListBlobsOptions options = new ListBlobsOptions(null, "a", null) + ListBlobsOptions options = new ListBlobsOptions().withPrefix("a") String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -918,7 +1011,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsHierarchySegment(null, "", options) + List blobs = cu.listBlobsHierarchySegment(null, "", options, null) .blockingGet().body().segment().blobItems() then: @@ -928,9 +1021,8 @@ class ContainerAPITest extends APISpec { def "List blobs hier options maxResults"() { setup: - ListBlobsOptions options = new ListBlobsOptions(new BlobListingDetails( - true, false, false, true, false), null, - 1) + ListBlobsOptions options = new ListBlobsOptions().withDetails(new BlobListingDetails().withCopy(true) + .withUncommittedBlobs(true)).withMaxResults(1) String normalName = "a" + generateBlobName() String copyName = "c" + generateBlobName() String metadataName = "m" + generateBlobName() @@ -938,7 +1030,7 @@ class ContainerAPITest extends APISpec { setupListBlobsTest(normalName, copyName, metadataName, uncommittedName) when: - List blobs = cu.listBlobsHierarchySegment(null, "", options) + List blobs = cu.listBlobsHierarchySegment(null, "", options, null) .blockingGet().body().segment().blobItems() then: @@ -948,9 +1040,9 @@ class ContainerAPITest extends APISpec { @Unroll def "List blobs hier options fail"() { when: - def options = new ListBlobsOptions(new BlobListingDetails(false, false, snapshots, - false, false), null, maxResults) - cu.listBlobsHierarchySegment(null, null, options) + def options = new ListBlobsOptions().withDetails(new BlobListingDetails().withSnapshots(snapshots)) + .withMaxResults(maxResults) + cu.listBlobsHierarchySegment(null, null, options, null) then: thrown(IllegalArgumentException) @@ -964,15 +1056,15 @@ class ContainerAPITest extends APISpec { def "List blobs hier delim"() { setup: AppendBlobURL blob = cu.createAppendBlobURL("a") - blob.create(null, null, null).blockingGet() + blob.create(null, null, null, null).blockingGet() AppendBlobURL dir = cu.createAppendBlobURL("b/") - dir.create(null, null, null).blockingGet() + dir.create(null, null, null, null).blockingGet() AppendBlobURL subBlob = cu.createAppendBlobURL("b/c") - subBlob.create(null, null, null).blockingGet() + subBlob.create(null, null, null, null).blockingGet() when: ContainerListBlobHierarchySegmentResponse response = - cu.listBlobsHierarchySegment(null, "/", null).blockingGet() + cu.listBlobsHierarchySegment(null, "/", null, null).blockingGet() then: response.body().segment().blobPrefixes().size() == 1 @@ -985,15 +1077,15 @@ class ContainerAPITest extends APISpec { setup: for (int i = 0; i < 10; i++) { PageBlobURL bu = cu.createPageBlobURL(generateBlobName()) - bu.create(512, null, null, null, null).blockingGet() + bu.create(512, null, null, null, null, null).blockingGet() } ContainerListBlobHierarchySegmentResponse response = cu.listBlobsHierarchySegment(null, "/", - new ListBlobsOptions(null, null, 6)) + new ListBlobsOptions().withMaxResults(6), null) .blockingGet() String marker = response.body().nextMarker() int firstSegmentSize = response.body().segment().blobItems().size() - response = cu.listBlobsHierarchySegment(marker, "/", null).blockingGet() + response = cu.listBlobsHierarchySegment(marker, "/", null, null).blockingGet() expect: firstSegmentSize == 6 @@ -1006,20 +1098,35 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.listBlobsHierarchySegment(null, ".", null).blockingGet() + cu.listBlobsHierarchySegment(null, ".", null, null).blockingGet() then: thrown(StorageException) } + def "List blobs hier context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerListBlobHierarchySegmentHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.listBlobsHierarchySegment(null, "/", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + @Unroll def "Acquire lease"() { setup: ContainerAcquireLeaseHeaders headers = - cu.acquireLease(proposedID, leaseTime, null).blockingGet().headers() + cu.acquireLease(proposedID, leaseTime, null, null).blockingGet().headers() when: - ContainerGetPropertiesHeaders properties = cu.getProperties(null).blockingGet() + ContainerGetPropertiesHeaders properties = cu.getProperties(null, null).blockingGet() .headers() then: @@ -1038,10 +1145,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Acquire lease AC"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) expect: - cu.acquireLease(null, -1, hac).blockingGet().statusCode() == 201 + cu.acquireLease(null, -1, mac, null).blockingGet().statusCode() == 201 where: modified | unmodified @@ -1053,10 +1160,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Acquire lease AC fail"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) when: - cu.acquireLease(null, -1, hac).blockingGet() + cu.acquireLease(null, -1, mac, null).blockingGet() then: thrown(StorageException) @@ -1070,10 +1177,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Acquire lease AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, null, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.acquireLease(null, -1, hac).blockingGet() + cu.acquireLease(null, -1, mac, null).blockingGet() then: thrown(IllegalArgumentException) @@ -1089,21 +1196,36 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.acquireLease(null, 50, null).blockingGet() + cu.acquireLease(null, 50, null, null).blockingGet() then: thrown(StorageException) } + def "Acquire lease context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(201, ContainerAcquireLeaseHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.acquireLease(null, 20, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Renew lease"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) Thread.sleep(16000) // Wait for the lease to expire to ensure we are actually renewing it - ContainerRenewLeaseHeaders headers = cu.renewLease(leaseID, null).blockingGet().headers() + ContainerRenewLeaseHeaders headers = cu.renewLease(leaseID, null, null).blockingGet().headers() expect: - cu.getProperties(null).blockingGet().headers().leaseState() == LeaseStateType.LEASED + cu.getProperties(null, null).blockingGet().headers().leaseState() == LeaseStateType.LEASED validateBasicHeaders(headers) headers.leaseId() != null } @@ -1112,10 +1234,10 @@ class ContainerAPITest extends APISpec { def "Renew lease AC"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) expect: - cu.renewLease(leaseID, hac).blockingGet().statusCode() == 200 + cu.renewLease(leaseID, mac, null).blockingGet().statusCode() == 200 where: modified | unmodified @@ -1128,10 +1250,10 @@ class ContainerAPITest extends APISpec { def "Renew lease AC fail"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) when: - cu.renewLease(leaseID, hac).blockingGet() + cu.renewLease(leaseID, mac, null).blockingGet() then: thrown(StorageException) @@ -1145,10 +1267,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Renew lease AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, null, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.renewLease(receivedLeaseID, hac).blockingGet() + cu.renewLease(receivedLeaseID, mac, null).blockingGet() then: thrown(IllegalArgumentException) @@ -1164,20 +1286,36 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.renewLease("id", null).blockingGet() + cu.renewLease("id", null, null).blockingGet() then: thrown(StorageException) } + def "Renew lease context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerRenewLeaseHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.renewLease("id", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + + def "Release lease"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) - ContainerReleaseLeaseHeaders headers = cu.releaseLease(leaseID, null).blockingGet().headers() + ContainerReleaseLeaseHeaders headers = cu.releaseLease(leaseID, null, null).blockingGet().headers() expect: - cu.getProperties(null).blockingGet().headers().leaseState() == LeaseStateType.AVAILABLE + cu.getProperties(null, null).blockingGet().headers().leaseState() == LeaseStateType.AVAILABLE validateBasicHeaders(headers) } @@ -1185,10 +1323,10 @@ class ContainerAPITest extends APISpec { def "Release lease AC"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) expect: - cu.releaseLease(leaseID, hac).blockingGet().statusCode() == 200 + cu.releaseLease(leaseID, mac, null).blockingGet().statusCode() == 200 where: modified | unmodified @@ -1201,10 +1339,10 @@ class ContainerAPITest extends APISpec { def "Release lease AC fail"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) when: - cu.releaseLease(leaseID, hac).blockingGet() + cu.releaseLease(leaseID, mac, null).blockingGet() then: thrown(StorageException) @@ -1218,10 +1356,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Release lease AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, null, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.releaseLease(receivedLeaseID, hac).blockingGet() + cu.releaseLease(receivedLeaseID, mac, null).blockingGet() then: thrown(IllegalArgumentException) @@ -1238,19 +1376,34 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.releaseLease("id", null).blockingGet() + cu.releaseLease("id", null, null).blockingGet() then: thrown(StorageException) } + def "Release lease context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerReleaseLeaseHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.releaseLease("id", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + @Unroll def "Break lease"() { setup: - cu.acquireLease(UUID.randomUUID().toString(), leaseTime, null).blockingGet() + cu.acquireLease(UUID.randomUUID().toString(), leaseTime, null, null).blockingGet() - ContainerBreakLeaseHeaders headers = cu.breakLease(breakPeriod, null).blockingGet().headers() - LeaseStateType state = cu.getProperties(null).blockingGet().headers().leaseState() + ContainerBreakLeaseHeaders headers = cu.breakLease(breakPeriod, null, null).blockingGet().headers() + LeaseStateType state = cu.getProperties(null, null).blockingGet().headers().leaseState() expect: state == LeaseStateType.BROKEN || state == LeaseStateType.BREAKING @@ -1272,10 +1425,10 @@ class ContainerAPITest extends APISpec { def "Break lease AC"() { setup: setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) expect: - cu.breakLease(null, hac).blockingGet().statusCode() == 202 + cu.breakLease(null, mac, null).blockingGet().statusCode() == 202 where: modified | unmodified @@ -1288,10 +1441,10 @@ class ContainerAPITest extends APISpec { def "Break lease AC fail"() { setup: setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) when: - cu.breakLease(null, hac).blockingGet() + cu.breakLease(null, mac, null).blockingGet() then: thrown(StorageException) @@ -1305,10 +1458,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Break lease AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, null, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.breakLease(null, hac).blockingGet() + cu.breakLease(null, mac, null).blockingGet() then: thrown(IllegalArgumentException) @@ -1324,22 +1477,37 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.breakLease(null, null).blockingGet() + cu.breakLease(null, null, null).blockingGet() then: thrown(StorageException) } + def "Break lease context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(202, ContainerBreakLeaseHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.breakLease(20, null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + def "Change lease"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) ContainerChangeLeaseHeaders headers = - cu.changeLease(leaseID, UUID.randomUUID().toString(), null) + cu.changeLease(leaseID, UUID.randomUUID().toString(), null, null) .blockingGet().headers() leaseID = headers.leaseId() expect: - cu.releaseLease(leaseID, null).blockingGet().statusCode() == 200 + cu.releaseLease(leaseID, null, null).blockingGet().statusCode() == 200 validateBasicHeaders(headers) } @@ -1347,10 +1515,10 @@ class ContainerAPITest extends APISpec { def "Change lease AC"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) expect: - cu.changeLease(leaseID, UUID.randomUUID().toString(), hac).blockingGet().statusCode() == 200 + cu.changeLease(leaseID, UUID.randomUUID().toString(), mac, null).blockingGet().statusCode() == 200 where: modified | unmodified @@ -1363,10 +1531,10 @@ class ContainerAPITest extends APISpec { def "Change lease AC fail"() { setup: String leaseID = setupContainerLeaseCondition(cu, receivedLeaseID) - HTTPAccessConditions hac = new HTTPAccessConditions(modified, unmodified, null, null) + def mac = new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) when: - cu.changeLease(leaseID, UUID.randomUUID().toString(), hac).blockingGet() + cu.changeLease(leaseID, UUID.randomUUID().toString(), mac, null).blockingGet() then: thrown(StorageException) @@ -1380,10 +1548,10 @@ class ContainerAPITest extends APISpec { @Unroll def "Change lease AC illegal"() { setup: - HTTPAccessConditions hac = new HTTPAccessConditions(null, null, match, noneMatch) + ModifiedAccessConditions mac = new ModifiedAccessConditions().withIfMatch(match).withIfNoneMatch(noneMatch) when: - cu.changeLease(receivedLeaseID, garbageLeaseID, hac).blockingGet() + cu.changeLease(receivedLeaseID, garbageLeaseID, mac, null).blockingGet() then: thrown(IllegalArgumentException) @@ -1399,12 +1567,27 @@ class ContainerAPITest extends APISpec { cu = primaryServiceURL.createContainerURL(generateContainerName()) when: - cu.changeLease("id", "id", null).blockingGet() + cu.changeLease("id", "id", null, null).blockingGet() then: thrown(StorageException) } + def "Change lease context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerChangeLeaseHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.changeLease("id", "id", null, defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + @Unroll def "Create URL special chars"() { // This test checks that we encode special characters in blob names correctly. @@ -1415,15 +1598,15 @@ class ContainerAPITest extends APISpec { BlobURL bu5 = cu.createBlockBlobURL(name) expect: - bu2.create(null, null, null).blockingGet().statusCode() == 201 - bu5.getProperties(null).blockingGet().statusCode() == 200 - bu3.create(512, null, null, null, null).blockingGet() + bu2.create(null, null, null, null).blockingGet().statusCode() == 201 + bu5.getProperties(null, null).blockingGet().statusCode() == 200 + bu3.create(512, null, null, null, null, null).blockingGet() .statusCode() == 201 bu4.upload(defaultFlowable, defaultDataSize, - null, null, null).blockingGet().statusCode() == 201 + null, null, null, null).blockingGet().statusCode() == 201 when: - List blobs = cu.listBlobsFlatSegment(null, null).blockingGet() + List blobs = cu.listBlobsFlatSegment(null, null, null).blockingGet() .body().segment().blobItems() then: @@ -1447,21 +1630,21 @@ class ContainerAPITest extends APISpec { BlobURL bu = cu.createAppendBlobURL("rootblob") expect: - bu.create(null, null, null).blockingGet().statusCode() == 201 + bu.create(null, null, null, null).blockingGet().statusCode() == 201 } def "Root implicit"() { setup: PipelineOptions po = new PipelineOptions() - po.client = getHttpClient() + po.withClient(getHttpClient()) HttpPipeline pipeline = StorageURL.createPipeline(primaryCreds, po) AppendBlobURL bu = new AppendBlobURL(new URL("http://xclientdev3.blob.core.windows.net/rootblob"), pipeline) when: - AppendBlobCreateResponse createResponse = bu.create(null, null, null) + AppendBlobCreateResponse createResponse = bu.create(null, null, null, null) .blockingGet() - BlobGetPropertiesResponse propsResponse = bu.getProperties(null).blockingGet() + BlobGetPropertiesResponse propsResponse = bu.getProperties(null, null).blockingGet() then: createResponse.statusCode() == 201 @@ -1475,7 +1658,7 @@ class ContainerAPITest extends APISpec { when: // Validate some basic operation. - webContainer.setAccessPolicy(null, null, null).blockingGet() + webContainer.setAccessPolicy(null, null, null, null).blockingGet() then: notThrown(StorageException) @@ -1496,7 +1679,7 @@ class ContainerAPITest extends APISpec { })) when: - withPipeline.create(null, null).blockingGet() + withPipeline.create(null, null, null).blockingGet() then: def e = thrown(Exception) @@ -1505,7 +1688,7 @@ class ContainerAPITest extends APISpec { def "Get account info"() { when: - def response = primaryServiceURL.getAccountInfo().blockingGet() + def response = primaryServiceURL.getAccountInfo(null).blockingGet() then: response.headers().date() != null @@ -1519,9 +1702,25 @@ class ContainerAPITest extends APISpec { when: ServiceURL serviceURL = new ServiceURL(primaryServiceURL.toURL(), StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions())) - serviceURL.createContainerURL(generateContainerName()).getAccountInfo().blockingGet() + serviceURL.createContainerURL(generateContainerName()).getAccountInfo(null).blockingGet() then: thrown(StorageException) } + + def "Get account info context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ContainerGetAccountInfoHeaders))) + + cu = cu.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + cu.getAccountInfo(defaultContext).blockingGet() + + then: + notThrown(RuntimeException) + } + } diff --git a/src/test/java/com/microsoft/azure/storage/HelperTest.groovy b/src/test/java/com/microsoft/azure/storage/HelperTest.groovy deleted file mode 100644 index 1647756c7f63..000000000000 --- a/src/test/java/com/microsoft/azure/storage/HelperTest.groovy +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 - -import com.microsoft.azure.storage.blob.BlobRange -import com.microsoft.azure.storage.blob.AccountSASResourceType -import com.microsoft.azure.storage.blob.AccountSASService -import com.microsoft.azure.storage.blob.AccountSASSignatureValues -import com.microsoft.azure.storage.blob.BlobSASPermission -import com.microsoft.azure.storage.blob.ContainerSASPermission -import com.microsoft.azure.storage.blob.IPRange -import com.microsoft.azure.storage.blob.SASProtocol -import com.microsoft.azure.storage.blob.ServiceSASSignatureValues -import com.microsoft.azure.storage.blob.StorageException -import com.microsoft.azure.storage.blob.Utility -import com.microsoft.azure.storage.blob.models.StorageErrorCode -import spock.lang.Unroll - -import java.time.OffsetDateTime -import java.time.ZoneOffset - - -class HelperTest extends APISpec { - - def "responseError"() { - when: - cu.listBlobsFlatSegment("garbage", null).blockingGet() - - then: - def e = thrown(StorageException) - e.errorCode() == StorageErrorCode.INVALID_QUERY_PARAMETER_VALUE - e.statusCode() == 400 - e.message().contains("Value for one of the query parameters specified in the request URI is invalid.") - e.getMessage().contains(">>>() { - @Override - Single>> apply(RetryReader.HTTPGetterInfo httpGetterInfo) { - bu.download(new BlobRange(httpGetterInfo.offset, httpGetterInfo.count), null, false) - } - })).blockingGet() == defaultData - - // Go DownloadResponse, Download, DownloadResponse.body - - // Test with the different kinds of errors that are retryable: Timeout, IOException, 500, 503--assert that the data at the end is still the same - Use the RetryTestFactory (or similar) - // Another policy which returns a custom flowable that injects an error after a certain amount of data. - // Different values of options. Valid and invalid. See Adam's comment on CR about count and offset. - // Null options and info parameters and null internal fields (null count) - } - - @Unroll - def "Successful"() { - setup: - RetryReaderMockFlowable flowable = new RetryReaderMockFlowable(scenario) - def info = new RetryReader.HTTPGetterInfo() - info.offset = 0 - info.count = flowable.getScenarioData().remaining() - - def options = new RetryReaderOptions() - options.maxRetryRequests = 5 - - def initialResponse = null - if (provideInitialResponse) { - initialResponse = flowable.getter(new RetryReader.HTTPGetterInfo()) - } - when: - RetryReader reader = new RetryReader(initialResponse, info, options, - new Function>>>() { - @Override - Single>> apply(RetryReader.HTTPGetterInfo i) { - flowable.getter(i) - } - }) - - then: - FlowableUtil.collectBytesInBuffer(reader).blockingGet() == flowable.getScenarioData() - flowable.getTryNumber() == tryNumber - - where: - scenario | tryNumber | provideInitialResponse - RetryReaderMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK | 1 | false - RetryReaderMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_MULTI_CHUNK | 1 | false - RetryReaderMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_STREAM_FAILURES | 4 | false - RetryReaderMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_INITIAL_RESPONSE | 1 | true - } - - @Unroll - def "Failure"() { - setup: - def flowable = new RetryReaderMockFlowable(scenario) - - def options = new RetryReaderOptions() - options.maxRetryRequests = 5 - - when: - RetryReader reader = new RetryReader(null, null, options, - new Function>>>() { - @Override - Single>> apply(RetryReader.HTTPGetterInfo i) { - flowable.getter(i) - } - }) - reader.blockingSubscribe() - - then: - def e = thrown(Throwable) // Blocking subscribe will wrap the IOException in a RuntimeException. - exceptionType.isInstance(e.getCause()) // The exception we throw is the cause of the RuntimeException. - flowable.getTryNumber() == tryNumber - - /* - tryNumber is 7 because the initial request is the first try, then it will fail when retryCount>maxRetryCount, - which is when retryCount=6 and therefore tryNumber=6 - */ - where: - scenario | exceptionType | tryNumber - RetryReaderMockFlowable.RR_TEST_SCENARIO_MAX_RETRIES_EXCEEDED | SocketTimeoutException | 7 - RetryReaderMockFlowable.RR_TEST_SCENARIO_NON_RETRYABLE_ERROR | Exception | 1 - RetryReaderMockFlowable.RR_TEST_SCENARIO_ERROR_GETTER_INITIAL | ClosedChannelException | 1 - RetryReaderMockFlowable.RR_TEST_SCENARIO_ERROR_GETTER_MIDDLE | RestException | 2 - } - - @Unroll - def "Nulls"() { - setup: - def flowable = new RetryReaderMockFlowable(RetryReaderMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK) - - when: - RetryReader reader = new RetryReader(null, null, options, - new Function>>>() { - @Override - Single>> apply(RetryReader.HTTPGetterInfo i) { - flowable.getter(i) - } - }) - reader.blockingSubscribe() - - then: - FlowableUtil.collectBytesInBuffer(reader).blockingGet() == flowable.getScenarioData() - flowable.getTryNumber() == tryNumber - - where: - info | options | tryNumber - null | new RetryReaderOptions() | 1 - new RetryReader.HTTPGetterInfo() | null | 1 - } - - def "Options fail"() { - setup: - def flowable = new RetryReaderMockFlowable(RetryReaderMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK) - - def options = new RetryReaderOptions() - options.maxRetryRequests = -1 - - when: - RetryReader reader = new RetryReader(null, null, options, - new Function>>>() { - @Override - Single>> apply(RetryReader.HTTPGetterInfo i) { - flowable.getter(i) - } - }) - reader.blockingSubscribe() - - then: - thrown(IllegalArgumentException) - } - - def "Getter fail"() { - setup: - def flowable = new RetryReaderMockFlowable(RetryReaderMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK) - - when: - RetryReader reader = new RetryReader(null, null, null, null) - reader.blockingSubscribe() - - then: - thrown(IllegalArgumentException) - } - - def "Info"() { - setup: - def flowable = new RetryReaderMockFlowable(RetryReaderMockFlowable.RR_TEST_SCENARIO_INFO_TEST) - def info = new RetryReader.HTTPGetterInfo() - info.offset = 20 - info.count = 10 - info.eTag = new ETag("etag") - def options = new RetryReaderOptions() - options.maxRetryRequests = 5 - - when: - RetryReader reader = new RetryReader(null, info, options, - new Function>>>() { - @Override - Single>> apply(RetryReader.HTTPGetterInfo i) { - flowable.getter(i) - } - }) - reader.blockingSubscribe() - - then: - flowable.tryNumber == 3 - } - - def "Info fail"() { - setup: - def info = new RetryReader.HTTPGetterInfo() - info.count = -1 - - when: - new RetryReader(null, info, null, - new Function>>>() { - @Override - Single>> apply(RetryReader.HTTPGetterInfo i) { - return null - } - }) - - then: - thrown(IllegalArgumentException) - } -} diff --git a/src/test/java/com/microsoft/azure/storage/Samples.java b/src/test/java/com/microsoft/azure/storage/Samples.java index b649f79d57b3..37d858a46595 100644 --- a/src/test/java/com/microsoft/azure/storage/Samples.java +++ b/src/test/java/com/microsoft/azure/storage/Samples.java @@ -31,6 +31,7 @@ import org.junit.Test; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; @@ -47,7 +48,7 @@ public class Samples { public static Single createContainerIfNotExists(ContainerURL containerURL) { - return containerURL.create(null, null).map((r) -> true).onErrorResumeNext((e) -> { + return containerURL.create(null, null, null).map((r) -> true).onErrorResumeNext((e) -> { if (e instanceof RestException) { RestException re = (RestException) e; if (re.getMessage().contains("ContainerAlreadyExists")) { @@ -60,7 +61,7 @@ public static Single createContainerIfNotExists(ContainerURL containerU } public static Single deleteContainerIfExists(ContainerURL containerURL) { - return containerURL.delete(null).map((r) -> true).onErrorResumeNext((e) -> { + return containerURL.delete(null, null).map((r) -> true).onErrorResumeNext((e) -> { if (e instanceof RestException) { RestException re = (RestException) e; if (re.getMessage().contains("ContainerNotFound")) { @@ -73,7 +74,7 @@ public static Single deleteContainerIfExists(ContainerURL containerURL) } public static Observable listBlobsLazy(ContainerURL containerURL, ListBlobsOptions listBlobsOptions) { - return containerURL.listBlobsFlatSegment(null, listBlobsOptions) + return containerURL.listBlobsFlatSegment(null, listBlobsOptions, null) .flatMapObservable((r) -> listContainersResultToContainerObservable(containerURL, listBlobsOptions, r)); } @@ -88,7 +89,7 @@ private static Observable listContainersResultToContainerObservable( System.out.println("Hit continuation in listing at " + response.body().segment().blobItems().get( response.body().segment().blobItems().size() - 1).name()); // Recursively add the continuation items to the observable. - result = result.concatWith(containerURL.listBlobsFlatSegment(response.body().nextMarker(), listBlobsOptions) + result = result.concatWith(containerURL.listBlobsFlatSegment(response.body().nextMarker(), listBlobsOptions, null) .flatMapObservable((r) -> listContainersResultToContainerObservable(containerURL, listBlobsOptions, r))); } @@ -141,7 +142,7 @@ Create a request pipeline that is used to process HTTP(S) requests and responses ContainerURL object that wraps the container's URL and a request pipeline (inherited from serviceURL). Note that container names require lowercase. */ - ContainerURL containerURL = serviceURL.createContainerURL("myjavacontainerbasic"); + ContainerURL containerURL = serviceURL.createContainerURL("myjavacontainerbasic" + System.currentTimeMillis()); /* Create a URL that references a to-be-created blob in your Azure Storage account's container. @@ -153,20 +154,22 @@ Create a request pipeline that is used to process HTTP(S) requests and responses String data = "Hello world!"; // Create the container on the service (with no metadata and no public access) - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(containerCreateResponse -> /* Create the blob with string (plain text) content. - NOTE: It is imperative that the provided length matches the actual length exactly. + NOTE: The Flowable containing the data must be replayable to support retries. That is, it must + yield the same data every time it is subscribed to. + NOTE: If the provided length does not match the actual length, this method will throw. */ blobURL.upload(Flowable.just(ByteBuffer.wrap(data.getBytes())), data.length(), - null, null, null)) + null, null, null, null)) .flatMap(blobUploadResponse -> // Download the blob's content. - blobURL.download(null, null, false)) + blobURL.download(null, null, false, null)) .flatMap(blobDownloadResponse -> // Verify that the blob data round-tripped correctly. - FlowableUtil.collectBytesInBuffer(blobDownloadResponse.body()) + FlowableUtil.collectBytesInBuffer(blobDownloadResponse.body(null)) .doOnSuccess(byteBuffer -> { if (byteBuffer.compareTo(ByteBuffer.wrap(data.getBytes())) != 0) { throw new Exception("The downloaded data does not match the uploaded data."); @@ -177,17 +180,16 @@ Create the blob with string (plain text) content. List the blob(s) in our container; since a container may hold millions of blobs, this is done one segment at a time. */ - containerURL.listBlobsFlatSegment(null, new ListBlobsOptions(null, null, - 1))) + containerURL.listBlobsFlatSegment(null, new ListBlobsOptions().withMaxResults(1), null)) .flatMap(containerListBlobFlatSegmentResponse -> // The asynchronous requests require we use recursion to continue our listing. listBlobsFlatHelper(containerURL, containerListBlobFlatSegmentResponse)) .flatMap(containerListBlobFlatSegmentResponse -> // Delete the blob we created earlier. - blobURL.delete(null, null)) + blobURL.delete(null, null, null)) .flatMap(blobDeleteResponse -> // Delete the container we created earlier. - containerURL.delete(null)) + containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -225,8 +227,7 @@ public Single listBlobsFlatHelper( The presence of the marker indicates that there are more blobs to list, so we make another call to listBlobsFlatSegment and pass the result through this helper function. */ - return containerURL.listBlobsFlatSegment(nextMarker, new ListBlobsOptions(null, null, - 1)) + return containerURL.listBlobsFlatSegment(nextMarker, new ListBlobsOptions().withMaxResults(1), null) .flatMap(containersListBlobFlatSegmentResponse -> listBlobsFlatHelper(containerURL, containersListBlobFlatSegmentResponse)); } @@ -270,7 +271,7 @@ next segment (after processing the current result segment listBlobsHierarchySegment and pass the result through this helper function. */ return containerURL.listBlobsHierarchySegment(nextMarker, response.body().delimiter(), - new ListBlobsOptions(null, null, 1)) + new ListBlobsOptions().withMaxResults(1), null) .flatMap(containersListBlobHierarchySegmentResponse -> listBlobsHierarchyHelper(containerURL, containersListBlobHierarchySegmentResponse)); } @@ -303,7 +304,7 @@ next segment (after processing the current result segment The presence of the marker indicates that there are more blobs to list, so we make another call to listContainersSegment and pass the result through this helper function. */ - return serviceURL.listContainersSegment(nextMarker, ListContainersOptions.DEFAULT) + return serviceURL.listContainersSegment(nextMarker, ListContainersOptions.DEFAULT, null) .flatMap(containersListBlobHierarchySegmentResponse -> listContainersHelper(serviceURL, response)); } @@ -332,17 +333,17 @@ public void exampleNewPipeline() throws MalformedURLException { - Maximum delay between retries is 3 seconds. - We will not retry against a secondary host. */ - po.requestRetryOptions = new RequestRetryOptions(RetryPolicyType.EXPONENTIAL, 3, 3, - 1000L, 3000L, null); + po.withRequestRetryOptions(new RequestRetryOptions(RetryPolicyType.EXPONENTIAL, 3, 3, + 1000L, 3000L, null)); /* Set LoggingOptions to control how each HTTP request and its response is logged. A successful response taking more than 200ms will be logged as a warning. */ - po.loggingOptions = new LoggingOptions(200); + po.withLoggingOptions(new LoggingOptions(200)); // Set LogOptions to control what & where all pipeline log events go. - po.logger = new HttpPipelineLogger() { + po.withLogger(new HttpPipelineLogger() { @Override public HttpPipelineLogLevel minimumLogLevel() { // Log all events from informational to more severe. @@ -364,7 +365,7 @@ public void log(HttpPipelineLogLevel httpPipelineLogLevel, String s, Object... o } logger.log(level, s); } - }; + }); /* Create a request pipeline object configured with credentials and with pipeline options. Once created, a @@ -405,8 +406,8 @@ public void log(HttpPipelineLogLevel httpPipelineLogLevel, String s, Object... o - Maximum delay between retries is 10 seconds. - We will not retry against a secondary host. */ - po.requestRetryOptions = new RequestRetryOptions(RetryPolicyType.EXPONENTIAL, 4, 60, - 5000L, 10000L, null); + po.withRequestRetryOptions(new RequestRetryOptions(RetryPolicyType.EXPONENTIAL, 4, 60, + 5000L, 10000L, null)); ContainerURL newContainerURL = containerURL.withPipeline( ServiceURL.createPipeline(new AnonymousCredentials(), po)); @@ -428,7 +429,7 @@ public void exampleStorageError() throws MalformedURLException { ContainerURL containerURL = new ContainerURL(new URL("http://myaccount.blob.core.windows.net/mycontainer"), StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions())); - containerURL.create(null, null) + containerURL.create(null, null, null) // An error occurred. .onErrorResumeNext(throwable -> { // Check if this error is from the service. @@ -480,28 +481,28 @@ public void exampleBlobURLParts() throws MalformedURLException, UnknownHostExcep // Now, we access the parts (this example prints them). System.out.println(String.join("\n", - parts.host, - parts.containerName, - parts.blobName, - parts.snapshot)); + parts.host(), + parts.containerName(), + parts.blobName(), + parts.snapshot())); System.out.println(""); - SASQueryParameters sas = parts.sasQueryParameters; + SASQueryParameters sas = parts.sasQueryParameters(); System.out.println(String.join("\n", - sas.getVersion(), - sas.getResource(), - sas.getStartTime().toString(), - sas.getExpiryTime().toString(), - sas.getPermissions(), - sas.getIpRange().toString(), - sas.getProtocol().toString(), - sas.getIdentifier(), - sas.getServices(), - sas.getSignature())); + sas.version(), + sas.resource(), + sas.startTime().toString(), + sas.expiryTime().toString(), + sas.permissions(), + sas.ipRange().toString(), + sas.protocol().toString(), + sas.identifier(), + sas.services(), + sas.signature())); // You can then change some of the fields and construct a new URL. - parts.sasQueryParameters = null; // Remove the SAS query parameters. - parts.snapshot = null; // Remove the snapshot timestamp. - parts.containerName = "othercontainer"; // Change the container name. + parts.withSasQueryParameters(null) // Remove the SAS query parameters. + .withSnapshot(null) // Remove the snapshot timestamp. + .withContainerName("othercontainer"); // Change the container name. // In this example, we'll keep the blob name as it is. // Construct a new URL from the parts: @@ -525,22 +526,22 @@ public void exampleAccountSASSignatureValues() throws InvalidKeyException, Malfo parameters. */ AccountSASSignatureValues values = new AccountSASSignatureValues(); - values.protocol = SASProtocol.HTTPS_ONLY; // Users MUST use HTTPS (not HTTP). - values.expiryTime = OffsetDateTime.now().plusDays(2); // 2 days before expiration. + values.withProtocol(SASProtocol.HTTPS_ONLY) // Users MUST use HTTPS (not HTTP). + .withExpiryTime(OffsetDateTime.now().plusDays(2)); // 2 days before expiration. - AccountSASPermission permission = new AccountSASPermission(); - permission.read = true; - permission.list = true; - values.permissions = permission.toString(); + AccountSASPermission permission = new AccountSASPermission() + .withRead(true) + .withList(true); + values.withPermissions(permission.toString()); - AccountSASService service = new AccountSASService(); - service.blob = true; - values.services = service.toString(); + AccountSASService service = new AccountSASService() + .withBlob(true); + values.withServices(service.toString()); - AccountSASResourceType resourceType = new AccountSASResourceType(); - resourceType.container = true; - resourceType.object = true; - values.resourceTypes = resourceType.toString(); + AccountSASResourceType resourceType = new AccountSASResourceType() + .withContainer(true) + .withObject(true); + values.withResourceTypes(resourceType.toString()); SASQueryParameters params = values.generateSASQueryParameters(credential); @@ -583,21 +584,21 @@ public void exampleBlobSASSignatureValues() throws InvalidKeyException, Malforme Set the desired SAS signature values and sign them with the shared key credentials to get the SAS query parameters. */ - ServiceSASSignatureValues values = new ServiceSASSignatureValues(); - values.protocol = SASProtocol.HTTPS_ONLY; // Users MUST use HTTPS (not HTTP). - values.expiryTime = OffsetDateTime.now().plusDays(2); // 2 days before expiration. - values.containerName = containerName; - values.blobName = blobName; + ServiceSASSignatureValues values = new ServiceSASSignatureValues() + .withProtocol(SASProtocol.HTTPS_ONLY) // Users MUST use HTTPS (not HTTP). + .withExpiryTime(OffsetDateTime.now().plusDays(2)) // 2 days before expiration. + .withContainerName(containerName) + .withBlobName(blobName); /* To produce a container SAS (as opposed to a blob SAS), assign to Permissions using ContainerSASPermissions, and make sure the blobName field is null (the default). */ - BlobSASPermission permission = new BlobSASPermission(); - permission.read = true; - permission.add = true; - permission.write = true; - values.permissions = permission.toString(); + BlobSASPermission permission = new BlobSASPermission() + .withRead(true) + .withAdd(true) + .withWrite(true); + values.withPermissions(permission.toString()); SASQueryParameters params = values.generateSASQueryParameters(credential); @@ -633,8 +634,8 @@ public void exampleContainerURL_SetPermissions() throws InvalidKeyException, Mal SharedKeyCredentials credential = new SharedKeyCredentials(accountName, accountKey); // Create a containerURL object that wraps the container's URL and a default pipeline. - URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/myjavacontainerpermissions", - accountName)); + URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/myjavacontainerpermissions" + + System.currentTimeMillis(), accountName)); ContainerURL containerURL = new ContainerURL(u, StorageURL.createPipeline(credential, new PipelineOptions())); /* @@ -650,16 +651,16 @@ public void exampleContainerURL_SetPermissions() throws InvalidKeyException, Mal String data = "Hello World!"; // Create the container (with no metadata and no public access) - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(containersCreateResponse -> blobURL.upload(Flowable.just(ByteBuffer.wrap(data.getBytes())), data.length(), - null, null, null) + null, null, null, null) ) .flatMap(blockBlobUploadResponse -> // Attempt to read the blob with anonymous credentials. - anonymousURL.download(null, null, false) + anonymousURL.download(null, null, false, null) ) - .toCompletable() + .ignoreElement() .onErrorResumeNext(throwable -> { /* We expected this error because the service returns an HTTP 404 status code when a blob exists but @@ -668,8 +669,8 @@ public void exampleContainerURL_SetPermissions() throws InvalidKeyException, Mal if (throwable instanceof RestException && ((RestException) throwable).response().statusCode() == 404) { // This is how we change the container's permission to allow public/anonymous access. - return containerURL.setAccessPolicy(PublicAccessType.BLOB, null, null) - .toCompletable(); + return containerURL.setAccessPolicy(PublicAccessType.BLOB, null, null, null) + .ignoreElement(); } else { return Completable.error(throwable); } @@ -682,10 +683,10 @@ public void exampleContainerURL_SetPermissions() throws InvalidKeyException, Mal .delay(31, TimeUnit.SECONDS) // Now this will work. .andThen(anonymousURL.download(null, null, - false)) + false, null)) .flatMap(blobDownloadResponse -> // Delete the container and the blob within in. - containerURL.delete(null)) + containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -705,30 +706,26 @@ public void exampleBlobAccessConditions() throws MalformedURLException, InvalidK URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/", accountName)); ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontaineraccessconditions"); + ContainerURL containerURL = s.createContainerURL("myjavacontaineraccessconditions" + + System.currentTimeMillis()); BlockBlobURL blobURL = containerURL.createBlockBlobURL("Data.txt"); // Create the container (unconditionally; succeeds) - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(containersCreateResponse -> // Create the blob (unconditionally; succeeds) blobURL.upload(Flowable.just(ByteBuffer.wrap("Text-1".getBytes())), "Text-1".length(), - null, null, null)) + null, null, null, null)) .flatMap(blockBlobUploadResponse -> { System.out.println("Success: " + blockBlobUploadResponse.statusCode()); // Download blob content if the blob has been modified since we uploaded it (fails). return blobURL.download(null, - new BlobAccessConditions( - new HTTPAccessConditions( - blockBlobUploadResponse.headers().lastModified(), - null, - null, - null), - null, - null, - null), - false); + new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince( + blockBlobUploadResponse.headers().lastModified())), + + false, null); }) .onErrorResumeNext(throwable -> { if (throwable instanceof RestException) { @@ -738,23 +735,17 @@ public void exampleBlobAccessConditions() throws MalformedURLException, InvalidK } // Download the blob content if the blob hasn't been modified in the last 24 hours (fails): return blobURL.download(null, - new BlobAccessConditions( - new HTTPAccessConditions( - null, - OffsetDateTime.now().minusDays(1), - null, - null), - null, - null, - null), - false); + new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfUnmodifiedSince( + OffsetDateTime.now().minusDays(1))), + false, null); }) /* onErrorResume next expects to return a Single of the same type. Here, we are changing operations, which means we will get a different return type and cannot directly recover from the error. To solve this, we go through a completable which will give us more flexibility with types. */ - .toCompletable() + .ignoreElement() .onErrorResumeNext(throwable -> { if (throwable instanceof RestException) { System.out.println("Failure: " + ((RestException) throwable).response().statusCode()); @@ -765,7 +756,7 @@ public void exampleBlobAccessConditions() throws MalformedURLException, InvalidK return Completable.complete(); }) // Get the blob properties to retrieve the current ETag. - .andThen(blobURL.getProperties(null)) + .andThen(blobURL.getProperties(null, null)) .flatMap(getPropertiesResponse -> /* Upload new content if the blob hasn't changed since the version identified by the ETag @@ -773,34 +764,19 @@ public void exampleBlobAccessConditions() throws MalformedURLException, InvalidK */ blobURL.upload(Flowable.just(ByteBuffer.wrap("Text-2".getBytes())), "Text-2".length(), null, null, - new BlobAccessConditions( - new HTTPAccessConditions( - null, - null, - new ETag(getPropertiesResponse.headers().eTag()), - null), - null, - null, - null)) - ) + new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfMatch( + getPropertiesResponse.headers().eTag())), null)) .flatMap(blockBlobUploadResponse -> { System.out.println("Success: " + blockBlobUploadResponse.statusCode()); // Download content if it has changed since the version identified by ETag (fails): return blobURL.download(null, - new BlobAccessConditions( - new HTTPAccessConditions( - null, - null, - null, - new ETag(blockBlobUploadResponse.headers().eTag()) - ), - null, - null, - null - ), false); + new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfNoneMatch( + blockBlobUploadResponse.headers().eTag())), false, null); }) - .toCompletable() + .ignoreElement() .onErrorResumeNext(throwable -> { if (throwable instanceof RestException) { System.out.println("Failure: " + ((RestException) throwable).response().statusCode()); @@ -811,21 +787,13 @@ public void exampleBlobAccessConditions() throws MalformedURLException, InvalidK return Completable.complete(); }).andThen( // Delete the blob if it exists (succeeds). - blobURL.delete(DeleteSnapshotsOptionType.INCLUDE, - new BlobAccessConditions( - new HTTPAccessConditions( - null, - null, - ETag.ANY, - null), - null, - null, - null) - ) - ) + blobURL.delete(DeleteSnapshotsOptionType.INCLUDE, + new BlobAccessConditions().withModifiedAccessConditions( + // Wildcard will match any etag. + new ModifiedAccessConditions().withIfMatch("*")), null)) .flatMap(blobDeleteResponse -> { System.out.println("Success: " + blobDeleteResponse.statusCode()); - return containerURL.delete(null); + return containerURL.delete(null, null); }) /* This will synchronize all the above operations. This is strongly discouraged for use in production as @@ -846,7 +814,8 @@ public void exampleMetadata_containers() throws MalformedURLException, InvalidKe URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/", accountName)); ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainercontainermetadata"); + ContainerURL containerURL = s.createContainerURL("myjavacontainercontainermetadata" + + System.currentTimeMillis()); /* Create a container with some metadata (string key/value pairs). @@ -856,10 +825,10 @@ Create a container with some metadata (string key/value pairs). Metadata metadata = new Metadata(); metadata.put("createdby", "Rick"); metadata.put("createdon", "4/13/18"); - containerURL.create(metadata, null) + containerURL.create(metadata, null, null) .flatMap(containersCreateResponse -> // Query the container's metadata. - containerURL.getProperties(null) + containerURL.getProperties(null, null) ) .flatMap(containersGetPropertiesResponse -> { Metadata receivedMetadata = new Metadata(containersGetPropertiesResponse.headers().metadata()); @@ -869,9 +838,9 @@ Create a container with some metadata (string key/value pairs). // Update the metadata and write it back to the container. receivedMetadata.put("createdby", "Mary"); // NOTE: The keyname is in all lowercase. - return containerURL.setMetadata(receivedMetadata, null); + return containerURL.setMetadata(receivedMetadata, null, null); }) - .flatMap(response -> containerURL.delete(null)) + .flatMap(response -> containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -896,11 +865,11 @@ public void exampleMetadata_blob() throws MalformedURLException, InvalidKeyExcep URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/", accountName)); ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainerblobmetadata"); + ContainerURL containerURL = s.createContainerURL("myjavacontainerblobmetadata" + System.currentTimeMillis()); BlockBlobURL blobURL = containerURL.createBlockBlobURL("Data.txt"); // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(containersCreateResponse -> { /* Create the blob with metadata (string key/value pairs). @@ -912,11 +881,11 @@ Create the blob with metadata (string key/value pairs). metadata.put("createdby", "Rick"); metadata.put("createdon", "4/13/18"); return blobURL.upload(Flowable.just(ByteBuffer.wrap("Text-1".getBytes())), "Text-1".length(), - null, metadata, null); + null, metadata, null, null); }) .flatMap(response -> // Query the blob's properties and metadata. - blobURL.getProperties(null)) + blobURL.getProperties(null, null)) .flatMap(response -> { // Show some of the blob's read-only properties. System.out.println(response.headers().blobType()); @@ -929,11 +898,11 @@ Create the blob with metadata (string key/value pairs). // Update the blob's metadata and write it back to the blob. Metadata receivedMetadata = new Metadata(response.headers().metadata()); receivedMetadata.put("createdby", "Joseph"); - return blobURL.setMetadata(receivedMetadata, null); + return blobURL.setMetadata(receivedMetadata, null, null); }) .flatMap(response -> // Delete the container. - containerURL.delete(null) + containerURL.delete(null, null) ) /* This will synchronize all the above operations. This is strongly discouraged for use in production as @@ -957,28 +926,23 @@ public void exampleBlobHTTPHeaders() throws MalformedURLException, InvalidKeyExc ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainerheaders"); + ContainerURL containerURL = s.createContainerURL("myjavacontainerheaders" + System.currentTimeMillis()); BlockBlobURL blobURL = containerURL.createBlockBlobURL("Data.txt"); // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(containersCreateResponse -> { /* Create the blob with HTTP headers. */ - BlobHTTPHeaders headers = new BlobHTTPHeaders( - null, - "attachment", - null, - null, - null, - "text/html; charset=utf-8"); + BlobHTTPHeaders headers = new BlobHTTPHeaders().withBlobContentDisposition("attachment") + .withBlobContentType("text/html; charset=utf-8"); return blobURL.upload(Flowable.just(ByteBuffer.wrap("Text-1".getBytes())), "Text-1".length(), - headers, null, null); + headers, null, null, null); }) .flatMap(response -> // Query the blob's properties and metadata. - blobURL.getProperties(null)) + blobURL.getProperties(null, null)) .flatMap(response -> { // Show some of the blob's read-only properties. System.out.println(response.headers().blobType()); @@ -995,19 +959,12 @@ public void exampleBlobHTTPHeaders() throws MalformedURLException, InvalidKeyExc will be cleared. In order to preserve the existing HTTP properties, they must be re-set along with the added or updated properties. */ - BlobHTTPHeaders headers = new BlobHTTPHeaders( - null, - null, - null, - null, - null, - "text/plain" - ); - return blobURL.setHTTPHeaders(headers, null); + BlobHTTPHeaders headers = new BlobHTTPHeaders().withBlobContentType("text/plain"); + return blobURL.setHTTPHeaders(headers, null, null); }) .flatMap(response -> // Delete the container. - containerURL.delete(null) + containerURL.delete(null, null) ) /* This will synchronize all the above operations. This is strongly discouraged for use in production as @@ -1037,13 +994,13 @@ public void exampleBlockBlobURL() throws MalformedURLException, InvalidKeyExcept ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainerblock"); + ContainerURL containerURL = s.createContainerURL("myjavacontainerblock" + System.currentTimeMillis()); BlockBlobURL blobURL = containerURL.createBlockBlobURL("Data.txt"); String[] data = {"Michael", "Gabriel", "Raphael", "John"}; // Create the container. We convert to an Observable to be able to work with the block list effectively. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMapObservable(response -> // Create an Observable that will yield each of the Strings one at a time. Observable.fromIterable(Arrays.asList(data)) @@ -1060,10 +1017,12 @@ public void exampleBlockBlobURL() throws MalformedURLException, InvalidKeyExcept /* Upload a block to this blob specifying the BlockID and its content (up to 100MB); this block is uncommitted. + NOTE: The Flowable containing the data must be replayable to support retries. That is, it must + yield the same data every time it is subscribed to. NOTE: It is imperative that the provided length match the actual length of the data exactly. */ return blobURL.stageBlock(blockId, Flowable.just(ByteBuffer.wrap(block.getBytes())), - block.length(), null) + block.length(), null, null) /* We do not care for any data on the response object, but we do want to keep track of the ID. @@ -1079,17 +1038,17 @@ public void exampleBlockBlobURL() throws MalformedURLException, InvalidKeyExcept NOTE: The block list order need not match the order in which the blocks were uploaded. The order of IDs in the commitBlockList call will determine the structure of the blob. */ - return blobURL.commitBlockList(idList, null, null, null); + return blobURL.commitBlockList(idList, null, null, null, null); }) .flatMap(response -> /* For the blob, show each block (ID and size) that is a committed part of it. It is also possible to include blocks that have been staged but not committed. */ - blobURL.getBlockList(BlockListType.ALL, null)) + blobURL.getBlockList(BlockListType.ALL, null, null)) .flatMap(response -> // Delete the container - containerURL.delete(null)) + containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -1114,34 +1073,38 @@ public void exampleAppendBlobURL() throws MalformedURLException, InvalidKeyExcep ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainerappend"); + ContainerURL containerURL = s.createContainerURL("myjavacontainerappend" + System.currentTimeMillis()); AppendBlobURL blobURL = containerURL.createAppendBlobURL("Data.txt"); // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Create the append blob. This creates a zero-length blob that we can now append to. - blobURL.create(null, null, null)) + blobURL.create(null, null, null, null)) .toObservable() .flatMap(response -> // This range will act as our for loop to create 5 blocks Observable.range(0, 5)) .concatMapCompletable(i -> { String text = String.format(Locale.ROOT, "Appending block #%d\n", i); - return blobURL.appendBlock(Flowable.just(ByteBuffer.wrap(text.getBytes())), text.length(), - null).toCompletable(); + /* + NOTE: The Flowable containing the data must be replayable to support retries. That is, it must + yield the same data every time it is subscribed to. + */ + return blobURL.appendBlock(Flowable.just(ByteBuffer.wrap(text.getBytes())), text.length(), null, + null).ignoreElement(); }) // Download the blob. - .andThen(blobURL.download(null, null, false)) + .andThen(blobURL.download(null, null, false, null)) .flatMap(response -> // Print out the data. - FlowableUtil.collectBytesInBuffer(response.body()) + FlowableUtil.collectBytesInBuffer(response.body(null)) .doOnSuccess(bytes -> System.out.println(new String(bytes.array()))) ) .flatMap(response -> // Delete the container. - containerURL.delete(null) + containerURL.delete(null, null) ) /* This will synchronize all the above operations. This is strongly discouraged for use in production as @@ -1163,15 +1126,15 @@ public void examplePageBlobURL() throws MalformedURLException, InvalidKeyExcepti URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/", accountName)); ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainerpage"); + ContainerURL containerURL = s.createContainerURL("myjavacontainerpage" + System.currentTimeMillis()); PageBlobURL blobURL = containerURL.createPageBlobURL("Data.txt"); // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Create the page blob with 4 512-byte pages. blobURL.create(4 * PageBlobURL.PAGE_BYTES, null, null, - null, null)) + null, null, null)) .flatMap(response -> { /* Upload data to a page. @@ -1182,8 +1145,12 @@ public void examplePageBlobURL() throws MalformedURLException, InvalidKeyExcepti for (int i = 0; i < PageBlobURL.PAGE_BYTES; i++) { data[i] = 'a'; } + /* + NOTE: The Flowable containing the data must be replayable to support retries. That is, it must + yield the same data every time it is subscribed to. + */ return blobURL.uploadPages(new PageRange().withStart(0).withEnd(PageBlobURL.PAGE_BYTES - 1), - Flowable.just(ByteBuffer.wrap(data)), null); + Flowable.just(ByteBuffer.wrap(data)), null, null); }) .flatMap(response -> { // Upload data to the third page in the blob. @@ -1193,11 +1160,11 @@ public void examplePageBlobURL() throws MalformedURLException, InvalidKeyExcepti } return blobURL.uploadPages(new PageRange().withStart(2 * PageBlobURL.PAGE_BYTES) .withEnd(3 * PageBlobURL.PAGE_BYTES - 1), - Flowable.just(ByteBuffer.wrap(data)), null); + Flowable.just(ByteBuffer.wrap(data)), null, null); }) .flatMap(response -> // Get the page ranges which have valid data. - blobURL.getPageRanges(null, null)) + blobURL.getPageRanges(null, null, null)) .flatMap(response -> { // Print the pages that are valid. for (PageRange range : response.body().pageRange()) { @@ -1207,11 +1174,11 @@ public void examplePageBlobURL() throws MalformedURLException, InvalidKeyExcepti // Clear and invalidate the first range. return blobURL.clearPages(new PageRange().withStart(0).withEnd(PageBlobURL.PAGE_BYTES - 1), - null); + null, null); }) .flatMap(response -> // Get the page ranges which have valid data. - blobURL.getPageRanges(null, null)) + blobURL.getPageRanges(null, null, null)) .flatMap(response -> { // Print the pages that are valid. for (PageRange range : response.body().pageRange()) { @@ -1220,16 +1187,16 @@ public void examplePageBlobURL() throws MalformedURLException, InvalidKeyExcepti } // Get the content of the whole blob. - return blobURL.download(null, null, false); + return blobURL.download(null, null, false, null); }) .flatMap(response -> // Print the received content. - FlowableUtil.collectBytesInBuffer(response.body()) + FlowableUtil.collectBytesInBuffer(response.body(null)) .doOnSuccess(data -> System.out.println(new String(data.array()))) .flatMap(data -> // Delete the container. - containerURL.delete(null)) + containerURL.delete(null, null)) ) /* This will synchronize all the above operations. This is strongly discouraged for use in production as @@ -1254,26 +1221,26 @@ public void example_blobSnapshot() throws MalformedURLException, InvalidKeyExcep ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainersnapshot"); + ContainerURL containerURL = s.createContainerURL("myjavacontainersnapshot" + System.currentTimeMillis()); BlockBlobURL blobURL = containerURL.createBlockBlobURL("Original.txt"); // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Create the original blob. blobURL.upload(Flowable.just(ByteBuffer.wrap("Some text".getBytes())), "Some text".length(), - null, null, null)) + null, null, null, null)) .flatMap(response -> // Create a snapshot of the original blob. - blobURL.createSnapshot(null, null)) + blobURL.createSnapshot(null, null, null)) .flatMap(response -> blobURL.upload(Flowable.just(ByteBuffer.wrap("New text".getBytes())), "New text".length(), - null, null, null) + null, null, null, null) .flatMap(response1 -> - blobURL.download(null, null, false)) + blobURL.download(null, null, false, null)) .flatMap(response1 -> // Print the received content. - FlowableUtil.collectBytesInBuffer(response1.body()) + FlowableUtil.collectBytesInBuffer(response1.body(null)) .doOnSuccess(data -> System.out.println(new String(data.array())))) .flatMap(response1 -> { @@ -1287,7 +1254,7 @@ public void example_blobSnapshot() throws MalformedURLException, InvalidKeyExcep BlockBlobURL baseBlob = snapshotURL.withSnapshot(null); return snapshotURL - .download(null, null, false) + .download(null, null, false, null) .flatMap(response2 -> /* List the blob(s) in our container, including their snapshots; since @@ -1295,8 +1262,7 @@ public void example_blobSnapshot() throws MalformedURLException, InvalidKeyExcep a time. */ containerURL.listBlobsFlatSegment(null, - new ListBlobsOptions(null, null, - 1))) + new ListBlobsOptions().withMaxResults(1), null)) .flatMap(response2 -> /* The asynchronous requests require we use recursion to continue our @@ -1305,11 +1271,11 @@ public void example_blobSnapshot() throws MalformedURLException, InvalidKeyExcep listBlobsFlatHelper(containerURL, response2)) .flatMap(response2 -> blobURL.startCopyFromURL(snapshotURL.toURL(), null, - null, null)); + null, null, null)); })) .flatMap(response -> // Delete the container. - containerURL.delete(null) + containerURL.delete(null, null) ) /* This will synchronize all the above operations. This is strongly discouraged for use in production as @@ -1338,23 +1304,23 @@ public void exampleBlobURL_startCopy() throws MalformedURLException, InvalidKeyE ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainercopy"); + ContainerURL containerURL = s.createContainerURL("myjavacontainercopy" + System.currentTimeMillis()); BlockBlobURL blobURL = containerURL.createBlockBlobURL("CopiedBlob.bin"); // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Start the copy from the source url to the destination, which is the url pointed to by blobURL blobURL.startCopyFromURL( new URL("https://cdn2.auth0.com/docs/media/addons/azure_blob.svg"), - null, null, null)) + null, null, null, null)) .flatMap(response -> - blobURL.getProperties(null)) + blobURL.getProperties(null, null)) .flatMap(response -> waitForCopyHelper(blobURL, response)) .flatMap(response -> // Delete the container we created earlier. - containerURL.delete(null)) + containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -1373,7 +1339,7 @@ public Single waitForCopyHelper(BlobURL blobURL, Blob } Thread.sleep(2000); - return blobURL.getProperties(null) + return blobURL.getProperties(null, null) .flatMap(response1 -> waitForCopyHelper(blobURL, response1)); @@ -1394,14 +1360,14 @@ public void exampleFileTransfer() throws IOException, InvalidKeyException { URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/", accountName)); ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainerparallelupload"); + ContainerURL containerURL = s.createContainerURL("myjavacontainerparallelupload" + System.currentTimeMillis()); String filename = "BigFile.bin"; BlockBlobURL blobURL = containerURL.createBlockBlobURL(filename); File tempFile = File.createTempFile("BigFile", ".bin"); tempFile.deleteOnExit(); // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> Single.using( () -> AsynchronousFileChannel.open(tempFile.toPath(), StandardOpenOption.WRITE), channel -> Single.fromFuture(channel @@ -1421,7 +1387,7 @@ public void exampleFileTransfer() throws IOException, InvalidKeyException { ) .flatMap(response -> // Delete the container. - containerURL.delete(null)) + containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -1445,35 +1411,37 @@ public void exampleReliableDownloadStream() throws IOException, InvalidKeyExcept URL u = new URL(String.format(Locale.ROOT, "https://%s.blob.core.windows.net/", accountName)); ServiceURL s = new ServiceURL(u, StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); - ContainerURL containerURL = s.createContainerURL("myjavacontainerretrystream"); + ContainerURL containerURL = s.createContainerURL("myjavacontainerretrystream" + System.currentTimeMillis()); BlockBlobURL blobURL = containerURL.createBlockBlobURL("Data.txt"); - RetryReaderOptions options = new RetryReaderOptions(); - options.maxRetryRequests = 5; + ReliableDownloadOptions options = new ReliableDownloadOptions(); + options.withMaxRetryRequests(5); File file = File.createTempFile("tempfile", "txt"); + FileOutputStream fos = new FileOutputStream(file); + fos.write(5); file.deleteOnExit(); /* - Passing RetryReaderOptions to a call to body() will ensure the download stream is intelligently retried in case + Passing ReliableDownloadOptions to a call to body() will ensure the download stream is intelligently retried in case of failures. The returned body is still a Flowable and may be used as a normal download stream. */ - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Upload some data to a blob Single.using(() -> AsynchronousFileChannel.open(file.toPath()), fileChannel -> TransferManager.uploadFileToBlockBlob(fileChannel, blobURL, - BlockBlobURL.MAX_STAGE_BLOCK_BYTES, TransferManager.UploadToBlockBlobOptions.DEFAULT), + BlockBlobURL.MAX_STAGE_BLOCK_BYTES, TransferManagerUploadToBlockBlobOptions.DEFAULT), AsynchronousFileChannel::close)) .flatMap(response -> - blobURL.download(null, null, false)) + blobURL.download(null, null, false, null)) .flatMapPublisher(response -> response.body(options)) .lastOrError() // Place holder for processing all the intermediary data. // After the last piece of data, clean up by deleting the container and all its contents. .flatMap(buffer -> // Delete the container - containerURL.delete(null)) + containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -1537,17 +1505,17 @@ public void exampleLazyEnumeration() throws MalformedURLException, InvalidKeyExc StorageURL.createPipeline(new SharedKeyCredentials(accountName, accountKey), new PipelineOptions())); ContainerURL containerURL = s.createContainerURL("myjavacontainerlistlazy"); - containerURL.create(null, null).toCompletable() + containerURL.create(null, null, null).toCompletable() .andThen(Observable.range(0, 5)) .flatMap(integer -> { AppendBlobURL bu = containerURL.createAppendBlobURL(integer.toString()); - return bu.create(null, null, null).toObservable(); + return bu.create(null, null, null, null).toObservable(); }) .ignoreElements() .andThen(listBlobsLazy(containerURL, null)) .doOnNext(b -> System.out.println("Blob: " + b.name())) .ignoreElements() - .andThen(containerURL.delete(null)) + .andThen(containerURL.delete(null, null)) /* This will synchronize all the above operations. This is strongly discouraged for use in production as it eliminates the benefits of asynchronous IO. We use it here to enable the sample to complete and @@ -1590,9 +1558,9 @@ Create a request pipeline that is used to process HTTP(S) requests and responses LoggingOptions loggingOptions = new LoggingOptions(2000); RequestRetryOptions requestRetryOptions = new RequestRetryOptions(RetryPolicyType.EXPONENTIAL, 5, 4, 1000L, 10000L, "secondary-host"); - PipelineOptions customOptions = new PipelineOptions(); - customOptions.loggingOptions = loggingOptions; - customOptions.requestRetryOptions = requestRetryOptions; + PipelineOptions customOptions = new PipelineOptions() + .withLoggingOptions(loggingOptions) + .withRequestRetryOptions(requestRetryOptions); StorageURL.createPipeline(new AnonymousCredentials(), customOptions); // @@ -1606,20 +1574,20 @@ Create a request pipeline that is used to process HTTP(S) requests and responses String data = "Hello world!"; // Create the container on the service (with no metadata and no public access) - Single downloadResponse = containerURL.create(null, null) + Single downloadResponse = containerURL.create(null, null, null) .flatMap(containersCreateResponse -> /* Create the blob with string (plain text) content. NOTE: It is imperative that the provided length matches the actual length exactly. */ blobURL.upload(Flowable.just(ByteBuffer.wrap(data.getBytes())), data.length(), - null, null, null)) + null, null, null, null)) .flatMap(blobUploadResponse -> // Download the blob's content. - blobURL.download(null, null, false)); + blobURL.download(null, null, false, null)); downloadResponse.flatMap(blobDownloadResponse -> // Verify that the blob data round-tripped correctly. - FlowableUtil.collectBytesInBuffer(blobDownloadResponse.body()) + FlowableUtil.collectBytesInBuffer(blobDownloadResponse.body(null)) .doOnSuccess(byteBuffer -> { if (byteBuffer.compareTo(ByteBuffer.wrap(data.getBytes())) != 0) { throw new Exception("The downloaded data does not match the uploaded data."); @@ -1629,7 +1597,7 @@ Create the blob with string (plain text) content. // // - containerURL.create(null, null) + containerURL.create(null, null, null) // An error occurred. .onErrorResumeNext(throwable -> { // Check if this error is from the service. @@ -1670,28 +1638,28 @@ Create the blob with string (plain text) content. // Now, we access the parts (this example prints them). System.out.println(String.join("\n", - parts.host, - parts.containerName, - parts.blobName, - parts.snapshot)); + parts.host(), + parts.containerName(), + parts.blobName(), + parts.snapshot())); System.out.println(""); - SASQueryParameters sas = parts.sasQueryParameters; + SASQueryParameters sas = parts.sasQueryParameters(); System.out.println(String.join("\n", - sas.getVersion(), - sas.getResource(), - sas.getStartTime().toString(), - sas.getExpiryTime().toString(), - sas.getPermissions(), - sas.getIpRange().toString(), - sas.getProtocol().toString(), - sas.getIdentifier(), - sas.getServices(), - sas.getSignature())); + sas.version(), + sas.resource(), + sas.startTime().toString(), + sas.expiryTime().toString(), + sas.permissions(), + sas.ipRange().toString(), + sas.protocol().toString(), + sas.identifier(), + sas.services(), + sas.signature())); // You can then change some of the fields and construct a new URL. - parts.sasQueryParameters = null; // Remove the SAS query parameters. - parts.snapshot = null; // Remove the snapshot timestamp. - parts.containerName = "othercontainer"; // Change the container name. + parts.withSasQueryParameters(null) // Remove the SAS query parameters. + .withSnapshot(null) // Remove the snapshot timestamp. + .withContainerName("othercontainer"); // Change the container name. // In this example, we'll keep the blob name as it is. // Construct a new URL from the parts: @@ -1709,22 +1677,22 @@ Create the blob with string (plain text) content. parameters. */ AccountSASSignatureValues values = new AccountSASSignatureValues(); - values.protocol = SASProtocol.HTTPS_ONLY; // Users MUST use HTTPS (not HTTP). - values.expiryTime = OffsetDateTime.now().plusDays(2); // 2 days before expiration. + values.withProtocol(SASProtocol.HTTPS_ONLY) // Users MUST use HTTPS (not HTTP). + .withExpiryTime(OffsetDateTime.now().plusDays(2)); // 2 days before expiration. - AccountSASPermission permission = new AccountSASPermission(); - permission.read = true; - permission.list = true; - values.permissions = permission.toString(); + AccountSASPermission permission = new AccountSASPermission() + .withRead(true) + .withList(true); + values.withPermissions(permission.toString()); - AccountSASService service = new AccountSASService(); - service.blob = true; - values.services = service.toString(); + AccountSASService service = new AccountSASService() + .withBlob(true); + values.withServices(service.toString()); - AccountSASResourceType resourceType = new AccountSASResourceType(); - resourceType.container = true; - resourceType.object = true; - values.resourceTypes = resourceType.toString(); + AccountSASResourceType resourceType = new AccountSASResourceType() + .withContainer(true) + .withObject(true); + values.withResourceTypes(resourceType.toString()); SASQueryParameters params = values.generateSASQueryParameters(credential); @@ -1761,21 +1729,21 @@ Create a ServiceURL object that wraps the serviceURL (and its SAS) and a pipelin Set the desired SAS signature values and sign them with the shared key credentials to get the SAS query parameters. */ - ServiceSASSignatureValues blobValues = new ServiceSASSignatureValues(); - blobValues.protocol = SASProtocol.HTTPS_ONLY; // Users MUST use HTTPS (not HTTP). - blobValues.expiryTime = OffsetDateTime.now().plusDays(2); // 2 days before expiration. - blobValues.containerName = containerName; - blobValues.blobName = blobName; + ServiceSASSignatureValues blobValues = new ServiceSASSignatureValues() + .withProtocol(SASProtocol.HTTPS_ONLY) // Users MUST use HTTPS (not HTTP). + .withExpiryTime(OffsetDateTime.now().plusDays(2)) // 2 days before expiration. + .withContainerName(containerName) + .withBlobName(blobName); /* To produce a container SAS (as opposed to a blob SAS), assign to Permissions using ContainerSASPermissions, and make sure the blobName field is null (the default). */ - BlobSASPermission blobPermission = new BlobSASPermission(); - blobPermission.read = true; - blobPermission.add = true; - blobPermission.write = true; - values.permissions = blobPermission.toString(); + BlobSASPermission blobPermission = new BlobSASPermission() + .withRead(true) + .withAdd(true) + .withWrite(true); + values.withPermissions(permission.toString()); SASQueryParameters serviceParams = values.generateSASQueryParameters(credential); @@ -1808,7 +1776,7 @@ Create a BlobURL object that wraps the blobURL (and its SAS) and a pipeline. Whe UUID.randomUUID().toString().getBytes()); // Create the container. We convert to an Observable to be able to work with the block list effectively. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMapObservable(response -> // Create an Observable that will yield each of the Strings one at a time. Observable.fromIterable(Arrays.asList(blockData)) @@ -1828,7 +1796,7 @@ Create a BlobURL object that wraps the blobURL (and its SAS) and a pipeline. Whe NOTE: It is imperative that the provided length match the actual length of the data exactly. */ return blockBlobURL.stageBlock(blockId, Flowable.just(ByteBuffer.wrap(block.getBytes())), - block.length(), null) + block.length(), null, null) /* We do not care for any data on the response object, but we do want to keep track of the ID. @@ -1845,169 +1813,172 @@ Create a BlobURL object that wraps the blobURL (and its SAS) and a pipeline. Whe of IDs in the commitBlockList call will determine the structure of the blob. */ idList.add(0, initialBlockID); - return blockBlobURL.commitBlockList(idList, null, null, null); + return blockBlobURL.commitBlockList(idList, null, null, null, null); }) .flatMap(response -> /* For the blob, show each block (ID and size) that is a committed part of it. It is also possible to include blocks that have been staged but not committed. */ - blockBlobURL.getBlockList(BlockListType.ALL, null)) + blockBlobURL.getBlockList(BlockListType.ALL, null, null)) .subscribe(); // // String blockID = Base64.getEncoder().encodeToString(UUID.randomUUID().toString().getBytes()); blockBlobURL.stageBlockFromURL(blockID, blobURL.toURL(), null, null, - null) + null, null) .flatMap(response -> blockBlobURL.commitBlockList(Arrays.asList(blockID), null, null, - null)) + null, null)) .subscribe(); // // // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Create the append blob. This creates a zero-length blob that we can now append to. - appendBlobURL.create(null, null, null)) + appendBlobURL.create(null, null, null, null)) .flatMapObservable(response -> // This range will act as our for loop to create 5 blocks Observable.range(0, 5)) .concatMapEager(i -> { String text = String.format(Locale.ROOT, "Appending block #%d\n", i); return appendBlobURL.appendBlock(Flowable.just(ByteBuffer.wrap(text.getBytes())), text.length(), - null).toObservable(); + null, null).toObservable(); }).subscribe(); // // // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Create the original blob. blobURL.upload(Flowable.just(ByteBuffer.wrap("Some text".getBytes())), "Some text".length(), - null, null, null)) + null, null, null, null)) .flatMap(response -> // Create a snapshot of the original blob. - blobURL.createSnapshot(null, null)) + blobURL.createSnapshot(null, null, null)) .flatMap(response -> { BlobURL snapshotURL = blobURL.withSnapshot(response.headers().snapshot()); - return snapshotURL.getProperties(null); + return snapshotURL.getProperties(null, null); }).subscribe(); // // // Create the container. - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Start the copy from the source url to the destination, which is the url pointed to by blobURL blobURL.startCopyFromURL( new URL("https://cdn2.auth0.com/docs/media/addons/azure_blob.svg"), - null, null, null)) + null, null, null, null)) .flatMap(response -> - blobURL.getProperties(null)) + blobURL.getProperties(null, null)) .flatMap(response -> waitForCopyHelper(blobURL, response)) .subscribe(); // // - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Start the copy from the source url to the destination, which is the url pointed to by blobURL blobURL.startCopyFromURL( new URL("https://cdn2.auth0.com/docs/media/addons/azure_blob.svg"), - null, null, null)) + null, null, null, null)) .flatMap(response -> - blobURL.getProperties(null)) + blobURL.getProperties(null, null)) .flatMap(response -> - blobURL.abortCopyFromURL(response.headers().copyId(), null)) + blobURL.abortCopyFromURL(response.headers().copyId(), null, null)) .subscribe(); // // - blobURL.delete(null, null) + blobURL.delete(null, null, null) .subscribe(); // // // This sample assumes that the account has a delete retention policy set. - blobURL.delete(null, null) + blobURL.delete(null, null, null) .flatMap(response -> - blobURL.undelete()) + blobURL.undelete(null)) .subscribe(); // // // BlockBlobs and PageBlobs have different sets of tiers. - blockBlobURL.setTier(AccessTier.HOT) + blockBlobURL.setTier(AccessTier.HOT, null, null) .subscribe(); - pageBlobURL.setTier(AccessTier.P6) + pageBlobURL.setTier(AccessTier.P6, null, null) .subscribe(); // // - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(containersCreateResponse -> /* Create the blob with string (plain text) content. NOTE: It is imperative that the provided length matches the actual length exactly. */ blobURL.upload(Flowable.just(ByteBuffer.wrap(data.getBytes())), data.length(), - null, null, null)) + null, null, null, null)) .flatMap(response -> - blobURL.getProperties(null)) + blobURL.getProperties(null, null)) .flatMap(response -> { Metadata newMetadata = new Metadata(response.headers().metadata()); // If one of the HTTP properties is set, all must be set again or they will be cleared. - BlobHTTPHeaders newHeaders = new BlobHTTPHeaders(response.headers().cacheControl(), - response.headers().contentDisposition(), response.headers().contentEncoding(), - "new language", response.headers().contentMD5(), "new content"); - return blobURL.setMetadata(newMetadata, null) - .flatMap(nextResponse -> blobURL.setHTTPHeaders(newHeaders, null)); + BlobHTTPHeaders newHeaders = new BlobHTTPHeaders() + .withBlobCacheControl(response.headers().cacheControl()) + .withBlobContentDisposition(response.headers().contentDisposition()) + .withBlobContentEncoding(response.headers().contentEncoding()) + .withBlobContentLanguage("new language") + .withBlobContentMD5(response.headers().contentMD5()) + .withBlobContentType("new content"); + return blobURL.setMetadata(newMetadata, null, null) + .flatMap(nextResponse -> blobURL.setHTTPHeaders(newHeaders, null, null)); }) .subscribe(); // // - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> - containerURL.getProperties(null)) + containerURL.getProperties(null, null)) .flatMap(response -> { Metadata metadata = new Metadata(); metadata.put("key", "value"); - return containerURL.setMetadata(metadata, null); + return containerURL.setMetadata(metadata, null, null); }) .flatMap(response -> - containerURL.delete(null)) + containerURL.delete(null, null)) .subscribe(); // // - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> { /* Create a SignedIdentifier that gives read permissions and expires one day for now. This means that any SAS associated with this policy has these properties. */ - BlobSASPermission perms = new BlobSASPermission(); - perms.read = true; + BlobSASPermission perms = new BlobSASPermission() + .withRead(true); SignedIdentifier id = new SignedIdentifier().withId("policy1").withAccessPolicy( new AccessPolicy().withPermission(perms.toString()).withExpiry(OffsetDateTime.now() .plusDays(1))); // Give public access to the blobs in this container and apply the SignedIdentifier. - return containerURL.setAccessPolicy(PublicAccessType.BLOB, Arrays.asList(id), null); + return containerURL.setAccessPolicy(PublicAccessType.BLOB, Arrays.asList(id), null, null); }) .subscribe(); // // - containerURL.listBlobsFlatSegment(null, new ListBlobsOptions(null, null, - 1)) + containerURL.listBlobsFlatSegment(null, new ListBlobsOptions().withMaxResults(1), null) .flatMap(containersListBlobFlatSegmentResponse -> // The asynchronous requests require we use recursion to continue our listing. listBlobsFlatHelper(containerURL, containersListBlobFlatSegmentResponse)) @@ -2015,8 +1986,7 @@ Create the blob with string (plain text) content. // // - containerURL.listBlobsHierarchySegment(null, "my_delimiter", - new ListBlobsOptions(null, null, 1)) + containerURL.listBlobsHierarchySegment(null, "my_delimiter", new ListBlobsOptions().withMaxResults(1), null) .flatMap(containersListBlobHierarchySegmentResponse -> // The asynchronous requests require we use recursion to continue our listing. listBlobsHierarchyHelper(containerURL, containersListBlobHierarchySegmentResponse)) @@ -2024,11 +1994,11 @@ Create the blob with string (plain text) content. // // - containerURL.create(null, null) + containerURL.create(null, null, null) .flatMap(response -> // Create the page blob with 4 512-byte pages. pageBlobURL.create(4 * PageBlobURL.PAGE_BYTES, null, null, - null, null)) + null, null, null)) .flatMap(response -> { /* Upload data to a page. @@ -2040,11 +2010,11 @@ Create the blob with string (plain text) content. pageData[i] = 'a'; } return pageBlobURL.uploadPages(new PageRange().withStart(0).withEnd(PageBlobURL.PAGE_BYTES - 1), - Flowable.just(ByteBuffer.wrap(pageData)), null); + Flowable.just(ByteBuffer.wrap(pageData)), null, null); }) .flatMap(response -> // Get the page ranges which have valid data. - pageBlobURL.getPageRanges(null, null)) + pageBlobURL.getPageRanges(null, null, null)) .flatMap(response -> { // Print the pages that are valid. for (PageRange range : response.body().pageRange()) { @@ -2054,21 +2024,21 @@ Create the blob with string (plain text) content. // Clear and invalidate the first range. return pageBlobURL.clearPages(new PageRange().withStart(0).withEnd(PageBlobURL.PAGE_BYTES - 1), - null); + null, null); }) .flatMap(response -> - pageBlobURL.resize(1024, null)) + pageBlobURL.resize(1024, null, null)) .flatMap(rsponse -> pageBlobURL.updateSequenceNumber(SequenceNumberActionType.INCREMENT, null, - null)) + null, null)) .subscribe(); // // pageBlobURL.create(4 * PageBlobURL.PAGE_BYTES, null, null, - null, null) + null, null, null) .flatMap(response -> - pageBlobURL.createSnapshot(null, null)) + pageBlobURL.createSnapshot(null, null, null)) .flatMap(response -> { /* Upload data to a page. @@ -2080,33 +2050,31 @@ Create the blob with string (plain text) content. pageData[i] = 'a'; } return pageBlobURL.uploadPages(new PageRange().withStart(0).withEnd(PageBlobURL.PAGE_BYTES - 1), - Flowable.just(ByteBuffer.wrap(pageData)), null) + Flowable.just(ByteBuffer.wrap(pageData)), null, null) // We still need access to the snapshotResponse. .flatMap(uploadResponse -> pageBlobURL.getPageRangesDiff(null, response.headers().snapshot(), - null)); + null, null)); }); // // PageBlobURL incrementalCopy = containerURL.createPageBlobURL("incremental"); - pageBlobURL.createSnapshot(null, null) + pageBlobURL.createSnapshot(null, null, null) .flatMap(response -> - incrementalCopy.copyIncremental(pageBlobURL.toURL(), response.headers().snapshot(), - null)) + incrementalCopy.copyIncremental(pageBlobURL.toURL(), response.headers().snapshot(), null, null)) .flatMap(response -> { byte[] pageData = new byte[PageBlobURL.PAGE_BYTES]; for (int i = 0; i < PageBlobURL.PAGE_BYTES; i++) { pageData[i] = 'a'; } return pageBlobURL.uploadPages(new PageRange().withStart(0).withEnd(PageBlobURL.PAGE_BYTES - 1), - Flowable.just(ByteBuffer.wrap(pageData)), null); + Flowable.just(ByteBuffer.wrap(pageData)), null, null); }) .flatMap(response -> - pageBlobURL.createSnapshot(null, null)) + pageBlobURL.createSnapshot(null, null, null)) .flatMap(response -> - incrementalCopy.copyIncremental(pageBlobURL.toURL(), response.headers().snapshot(), - null)) + incrementalCopy.copyIncremental(pageBlobURL.toURL(), response.headers().snapshot(), null, null)) .subscribe(); /* The result is a new blob with two new snapshots that correspond to the source blob snapshots but with different @@ -2115,29 +2083,29 @@ Create the blob with string (plain text) content. // // - blobURL.acquireLease(null, 20, null) + blobURL.acquireLease(null, 20, null, null) .flatMap(response -> - blobURL.changeLease(response.headers().leaseId(), "proposed", null)) + blobURL.changeLease(response.headers().leaseId(), "proposed", null, null)) .flatMap(response -> - blobURL.renewLease(response.headers().leaseId(), null)) + blobURL.renewLease(response.headers().leaseId(), null, null)) .flatMap(response -> - blobURL.breakLease(null, null) + blobURL.breakLease(null, null, null) .flatMap(breakResponse -> - blobURL.releaseLease(response.headers().leaseId(), null))) + blobURL.releaseLease(response.headers().leaseId(), null, null))) .subscribe(); // // - containerURL.acquireLease(null, 20, null) + containerURL.acquireLease(null, 20, null, null) .flatMap(response -> containerURL.changeLease(response.headers().leaseId(), "proposed", - null)) + null, null)) .flatMap(response -> - containerURL.renewLease(response.headers().leaseId(), null)) + containerURL.renewLease(response.headers().leaseId(), null, null)) .flatMap(response -> - containerURL.breakLease(null, null) + containerURL.breakLease(null, null, null) .flatMap(breakResponse -> - containerURL.releaseLease(response.headers().leaseId(), null))) + containerURL.releaseLease(response.headers().leaseId(), null, null))) .subscribe(); // @@ -2165,29 +2133,29 @@ Create the blob with string (plain text) content. ) .flatMap(response -> // Delete the container. - containerURL.delete(null)); + containerURL.delete(null, null)); // // - serviceURL.getProperties() + serviceURL.getProperties(null) .flatMap(response -> { StorageServiceProperties newProps = response.body(); // Remove the delete retention policy to disable soft delete. newProps.withDeleteRetentionPolicy(null); - return serviceURL.setProperties(newProps); + return serviceURL.setProperties(newProps, null); }) .subscribe(); // // - serviceURL.getStatistics() + serviceURL.getStatistics(null) .subscribe(); // // - serviceURL.listContainersSegment(null, ListContainersOptions.DEFAULT) + serviceURL.listContainersSegment(null, ListContainersOptions.DEFAULT, null) .flatMap(listContainersSegmentResponse -> // The asynchronous requests require we use recursion to continue our listing. listContainersHelper(serviceURL, listContainersSegmentResponse)) @@ -2195,11 +2163,11 @@ Create the blob with string (plain text) content. // // - serviceURL.getAccountInfo() + serviceURL.getAccountInfo(null) .subscribe(); - containerURL.getAccountInfo() + containerURL.getAccountInfo(null) .subscribe(); - blobURL.getAccountInfo() + blobURL.getAccountInfo(null) .subscribe(); // } diff --git a/src/test/java/com/microsoft/azure/storage/ServiceAPITest.groovy b/src/test/java/com/microsoft/azure/storage/ServiceAPITest.groovy index 760e84197729..ddd1e033c576 100644 --- a/src/test/java/com/microsoft/azure/storage/ServiceAPITest.groovy +++ b/src/test/java/com/microsoft/azure/storage/ServiceAPITest.groovy @@ -31,14 +31,16 @@ import com.microsoft.azure.storage.blob.models.CorsRule import com.microsoft.azure.storage.blob.models.Logging import com.microsoft.azure.storage.blob.models.Metrics import com.microsoft.azure.storage.blob.models.RetentionPolicy +import com.microsoft.azure.storage.blob.models.ServiceGetAccountInfoHeaders +import com.microsoft.azure.storage.blob.models.ServiceGetPropertiesHeaders +import com.microsoft.azure.storage.blob.models.ServiceGetStatisticsHeaders import com.microsoft.azure.storage.blob.models.ServiceGetStatisticsResponse +import com.microsoft.azure.storage.blob.models.ServiceListContainersSegmentHeaders import com.microsoft.azure.storage.blob.models.ServiceListContainersSegmentResponse import com.microsoft.azure.storage.blob.models.ServiceSetPropertiesHeaders import com.microsoft.azure.storage.blob.models.StaticWebsite import com.microsoft.azure.storage.blob.models.StorageServiceProperties -import spock.lang.Unroll - -import java.lang.annotation.Retention +import com.microsoft.rest.v2.http.HttpPipeline class ServiceAPITest extends APISpec { def setup() { @@ -53,7 +55,7 @@ class ServiceAPITest extends APISpec { .withRetentionPolicy(disabled)) .withLogging(new Logging().withVersion("1.0") .withRetentionPolicy(disabled)) - .withDefaultServiceVersion("2018-03-28")).blockingGet() + .withDefaultServiceVersion("2018-03-28"), null).blockingGet() } def cleanup() { @@ -68,14 +70,14 @@ class ServiceAPITest extends APISpec { .withRetentionPolicy(disabled)) .withLogging(new Logging().withVersion("1.0") .withRetentionPolicy(disabled)) - .withDefaultServiceVersion("2018-03-28")).blockingGet() + .withDefaultServiceVersion("2018-03-28"), null).blockingGet() } def "List containers"() { when: ServiceListContainersSegmentResponse response = - primaryServiceURL.listContainersSegment(null, new ListContainersOptions(null, - containerPrefix, null)).blockingGet() + primaryServiceURL.listContainersSegment(null, new ListContainersOptions().withPrefix(containerPrefix), + null).blockingGet() then: for (ContainerItem c : response.body().containerItems()) { @@ -97,16 +99,16 @@ class ServiceAPITest extends APISpec { setup: for (int i = 0; i < 10; i++) { ContainerURL cu = primaryServiceURL.createContainerURL(generateContainerName()) - cu.create(null, null).blockingGet() + cu.create(null, null, null).blockingGet() } ServiceListContainersSegmentResponse response = primaryServiceURL.listContainersSegment(null, - new ListContainersOptions(null, null, 5)).blockingGet() + new ListContainersOptions().withMaxResults(5), null).blockingGet() String marker = response.body().nextMarker() String firstContainerName = response.body().containerItems().get(0).name() response = primaryServiceURL.listContainersSegment(marker, - new ListContainersOptions(null, null, 5)).blockingGet() + new ListContainersOptions().withMaxResults(5), null).blockingGet() expect: // Assert that the second segment is indeed after the first alphabetically @@ -118,37 +120,52 @@ class ServiceAPITest extends APISpec { Metadata metadata = new Metadata() metadata.put("foo", "bar") cu = primaryServiceURL.createContainerURL("aaa" + generateContainerName()) - cu.create(metadata, null).blockingGet() + cu.create(metadata, null, null).blockingGet() expect: primaryServiceURL.listContainersSegment(null, - new ListContainersOptions(new ContainerListingDetails(true), - "aaa" + containerPrefix, null)).blockingGet().body().containerItems() + new ListContainersOptions().withDetails(new ContainerListingDetails().withMetadata(true)) + .withPrefix("aaa" + containerPrefix), null).blockingGet().body().containerItems() .get(0).metadata() == metadata // Container with prefix "aaa" will not be cleaned up by normal test cleanup. - cu.delete(null).blockingGet().statusCode() == 202 + cu.delete(null, null).blockingGet().statusCode() == 202 } def "List containers maxResults"() { setup: for (int i = 0; i < 11; i++) { - primaryServiceURL.createContainerURL(generateContainerName()).create(null, null) + primaryServiceURL.createContainerURL(generateContainerName()).create(null, null, null) .blockingGet() } expect: primaryServiceURL.listContainersSegment(null, - new ListContainersOptions(null, null, 10)) + new ListContainersOptions().withMaxResults(10), null) .blockingGet().body().containerItems().size() == 10 } def "List containers error"() { when: - primaryServiceURL.listContainersSegment("garbage", null).blockingGet() + primaryServiceURL.listContainersSegment("garbage", null, null).blockingGet() then: thrown(StorageException) } + def "List containers context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ServiceListContainersSegmentHeaders))) + + def su = primaryServiceURL.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + su.listContainersSegment(null, null, defaultContext) + + then: + notThrown(RuntimeException) + } + def validatePropsSet(StorageServiceProperties sent, StorageServiceProperties received) { return received.logging().read() == sent.logging().read() && received.logging().delete() == sent.logging().delete() && @@ -212,13 +229,13 @@ class ServiceAPITest extends APISpec { .withDeleteRetentionPolicy(retentionPolicy) .withStaticWebsite(website) - ServiceSetPropertiesHeaders headers = primaryServiceURL.setProperties(sentProperties) + ServiceSetPropertiesHeaders headers = primaryServiceURL.setProperties(sentProperties, null) .blockingGet().headers() // Service properties may take up to 30s to take effect. If they weren't already in place, wait. sleep(30 * 1000) - StorageServiceProperties receivedProperties = primaryServiceURL.getProperties() + StorageServiceProperties receivedProperties = primaryServiceURL.getProperties(null) .blockingGet().body() then: @@ -233,28 +250,58 @@ class ServiceAPITest extends APISpec { when: new ServiceURL(new URL("https://error.blob.core.windows.net"), StorageURL.createPipeline(primaryCreds, new PipelineOptions())) - .setProperties(new StorageServiceProperties()).blockingGet() + .setProperties(new StorageServiceProperties(), null).blockingGet() then: thrown(StorageException) } + def "Set props context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ServiceSetPropertiesHeaders))) + + def su = primaryServiceURL.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + su.setProperties(new StorageServiceProperties(), defaultContext) + + then: + notThrown(RuntimeException) + } + def "Get props error"() { when: new ServiceURL(new URL("https://error.blob.core.windows.net"), - StorageURL.createPipeline(primaryCreds, new PipelineOptions())).getProperties().blockingGet() + StorageURL.createPipeline(primaryCreds, new PipelineOptions())).getProperties(null).blockingGet() then: thrown(StorageException) } + def "Get props context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ServiceGetPropertiesHeaders))) + + def su = primaryServiceURL.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + su.getProperties(defaultContext) + + then: + notThrown(RuntimeException) + } + def "Get stats"() { setup: BlobURLParts parts = URLParser.parse(primaryServiceURL.toURL()) - parts.host = "xclientdev3-secondary.blob.core.windows.net" + parts.withHost("xclientdev3-secondary.blob.core.windows.net") ServiceURL secondary = new ServiceURL(parts.toURL(), StorageURL.createPipeline(primaryCreds, new PipelineOptions())) - ServiceGetStatisticsResponse response = secondary.getStatistics().blockingGet() + ServiceGetStatisticsResponse response = secondary.getStatistics(null).blockingGet() expect: response.headers().version() != null @@ -266,15 +313,30 @@ class ServiceAPITest extends APISpec { def "Get stats error"() { when: - primaryServiceURL.getStatistics().blockingGet() + primaryServiceURL.getStatistics(null).blockingGet() then: thrown(StorageException) } + def "Get stats context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ServiceGetStatisticsHeaders))) + + def su = primaryServiceURL.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + su.getStatistics(defaultContext) + + then: + notThrown(RuntimeException) + } + def "Get account info"() { when: - def response = primaryServiceURL.getAccountInfo().blockingGet() + def response = primaryServiceURL.getAccountInfo(null).blockingGet() then: response.headers().date() != null @@ -288,9 +350,24 @@ class ServiceAPITest extends APISpec { when: ServiceURL serviceURL = new ServiceURL(primaryServiceURL.toURL(), StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions())) - serviceURL.getAccountInfo().blockingGet() + serviceURL.getAccountInfo(null).blockingGet() then: thrown(StorageException) } + + def "Get account info context"() { + setup: + def pipeline = + HttpPipeline.build(getStubFactory(getContextStubPolicy(200, ServiceGetAccountInfoHeaders))) + + def su = primaryServiceURL.withPipeline(pipeline) + + when: + // No service call is made. Just satisfy the parameters. + su.getAccountInfo(defaultContext) + + then: + notThrown(RuntimeException) + } } diff --git a/src/test/java/com/microsoft/azure/storage/TransferManagerTest.groovy b/src/test/java/com/microsoft/azure/storage/TransferManagerTest.groovy index 9212db3551a9..484c1051ec8e 100644 --- a/src/test/java/com/microsoft/azure/storage/TransferManagerTest.groovy +++ b/src/test/java/com/microsoft/azure/storage/TransferManagerTest.groovy @@ -3,9 +3,12 @@ package com.microsoft.azure.storage import com.microsoft.azure.storage.blob.* import com.microsoft.azure.storage.blob.models.BlobDownloadHeaders import com.microsoft.azure.storage.blob.models.BlobGetPropertiesResponse +import com.microsoft.azure.storage.blob.models.BlobHTTPHeaders import com.microsoft.azure.storage.blob.models.BlobType import com.microsoft.azure.storage.blob.models.BlockBlobCommitBlockListResponse import com.microsoft.azure.storage.blob.models.BlockBlobUploadResponse +import com.microsoft.azure.storage.blob.models.LeaseAccessConditions +import com.microsoft.azure.storage.blob.models.ModifiedAccessConditions import com.microsoft.azure.storage.blob.models.StorageErrorCode import com.microsoft.rest.v2.http.HttpPipeline import com.microsoft.rest.v2.http.HttpRequest @@ -38,14 +41,13 @@ class TransferManagerTest extends APISpec { // Block length will be ignored for single shot. CommonRestResponse response = TransferManager.uploadFileToBlockBlob(channel, bu, (int) (BlockBlobURL.MAX_STAGE_BLOCK_BYTES / 10), - new TransferManager.UploadToBlockBlobOptions(null, null, null, + new TransferManagerUploadToBlockBlobOptions(null, null, null, null, 20)).blockingGet() then: responseType.isInstance(response.response()) // Ensure we did the correct type of operation. validateBasicHeaders(response) - compareDataToFile(bu.download(null, null, false).blockingGet().body(), - file) + compareDataToFile(bu.download(null, null, false, null).blockingGet().body(null), file) cleanup: channel.close() @@ -126,11 +128,13 @@ class TransferManagerTest extends APISpec { when: TransferManager.uploadFileToBlockBlob(channel, bu, BlockBlobURL.MAX_STAGE_BLOCK_BYTES, - new TransferManager.UploadToBlockBlobOptions(null, new BlobHTTPHeaders(cacheControl, - contentDisposition, contentEncoding, contentLanguage, contentMD5, contentType), null, + new TransferManagerUploadToBlockBlobOptions(null, new BlobHTTPHeaders() + .withBlobCacheControl(cacheControl).withBlobContentDisposition(contentDisposition) + .withBlobContentEncoding(contentEncoding).withBlobContentLanguage(contentLanguage) + .withBlobContentMD5(contentMD5).withBlobContentType(contentType), null, null, null)).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: validateBlobHeaders(response.headers(), cacheControl, contentDisposition, contentEncoding, contentLanguage, @@ -165,9 +169,9 @@ class TransferManagerTest extends APISpec { when: TransferManager.uploadFileToBlockBlob(channel, bu, BlockBlobURL.MAX_STAGE_BLOCK_BYTES, - new TransferManager.UploadToBlockBlobOptions(null, null, metadata, + new TransferManagerUploadToBlockBlobOptions(null, null, metadata, null, null)).blockingGet() - BlobGetPropertiesResponse response = bu.getProperties(null).blockingGet() + BlobGetPropertiesResponse response = bu.getProperties(null, null).blockingGet() then: response.statusCode() == 200 @@ -187,17 +191,18 @@ class TransferManagerTest extends APISpec { @Unroll def "Upload file AC"() { setup: - bu.upload(defaultFlowable, defaultDataSize, null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) def channel = AsynchronousFileChannel.open(getRandomFile(dataSize).toPath()) expect: TransferManager.uploadFileToBlockBlob(channel, bu, BlockBlobURL.MAX_STAGE_BLOCK_BYTES, - new TransferManager.UploadToBlockBlobOptions(null, null, null, bac, + new TransferManagerUploadToBlockBlobOptions(null, null, null, bac, null)) .blockingGet().statusCode() == 201 @@ -205,35 +210,36 @@ class TransferManagerTest extends APISpec { channel.close() where: - dataSize | modified | unmodified | match | noneMatch | leaseID - 10 | null | null | null | null | null - 10 | oldDate | null | null | null | null - 10 | null | newDate | null | null | null - 10 | null | null | receivedEtag | null | null - 10 | null | null | null | garbageEtag | null - 10 | null | null | null | null | receivedLeaseID - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | null | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | oldDate | null | null | null | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | newDate | null | null | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | receivedEtag | null | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | garbageEtag | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | null | receivedLeaseID + dataSize | modified | unmodified | match | noneMatch | leaseID + 10 | null | null | null | null | null + 10 | oldDate | null | null | null | null + 10 | null | newDate | null | null | null + 10 | null | null | receivedEtag | null | null + 10 | null | null | null | garbageEtag | null + 10 | null | null | null | null | receivedLeaseID + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | null | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | oldDate | null | null | null | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | newDate | null | null | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | receivedEtag | null | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | garbageEtag | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | null | receivedLeaseID } @Unroll def "Upload file AC fail"() { setup: - bu.upload(defaultFlowable, defaultDataSize, null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) def channel = AsynchronousFileChannel.open(getRandomFile(dataSize).toPath()) when: TransferManager.uploadFileToBlockBlob(channel, bu, BlockBlobURL.MAX_STAGE_BLOCK_BYTES, - new TransferManager.UploadToBlockBlobOptions(null, null, null, + new TransferManagerUploadToBlockBlobOptions(null, null, null, bac, null)) .blockingGet() @@ -246,17 +252,17 @@ class TransferManagerTest extends APISpec { channel.close() where: - dataSize | modified | unmodified | match | noneMatch | leaseID - 10 | newDate | null | null | null | null - 10 | null | oldDate | null | null | null - 10 | null | null | garbageEtag | null | null - 10 | null | null | null | receivedEtag | null - 10 | null | null | null | null | garbageLeaseID - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | newDate | null | null | null | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | oldDate | null | null | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | garbageEtag | null | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | receivedEtag | null - BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | null | garbageLeaseID + dataSize | modified | unmodified | match | noneMatch | leaseID + 10 | newDate | null | null | null | null + 10 | null | oldDate | null | null | null + 10 | null | null | garbageEtag | null | null + 10 | null | null | null | receivedEtag | null + 10 | null | null | null | null | garbageLeaseID + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | newDate | null | null | null | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | oldDate | null | null | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | garbageEtag | null | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | receivedEtag | null + BlockBlobURL.MAX_UPLOAD_BLOB_BYTES + 10 | null | null | null | null | garbageLeaseID } /* @@ -264,12 +270,13 @@ class TransferManagerTest extends APISpec { whatever means of getting data from a file we use produces a replayable Flowable so that we abide by our own contract. */ + def "Upload replayable flowable"() { setup: // Write default data to a file - File file = File.createTempFile(UUID.randomUUID().toString(), ".txt"); - file.deleteOnExit(); - FileOutputStream fos = new FileOutputStream(file); + File file = File.createTempFile(UUID.randomUUID().toString(), ".txt") + file.deleteOnExit() + FileOutputStream fos = new FileOutputStream(file) fos.write(defaultData.array()) // Mock a response that will always be retried. @@ -312,7 +319,7 @@ class TransferManagerTest extends APISpec { def "Upload options fail"() { when: - new TransferManager.UploadToBlockBlobOptions(null, null, null, + new TransferManagerUploadToBlockBlobOptions(null, null, null, null, -1) then: @@ -387,29 +394,29 @@ class TransferManagerTest extends APISpec { TransferManager.downloadBlobToFile(outChannel, bu, range, null).blockingGet() then: - compareFiles(channel, range.getOffset(), range.getCount(), outChannel) + compareFiles(channel, range.offset(), range.count(), outChannel) cleanup: channel.close() outChannel.close() where: - file | range | dataSize - getRandomFile(defaultDataSize) | new BlobRange(0, defaultDataSize) | defaultDataSize - getRandomFile(defaultDataSize) | new BlobRange(1, defaultDataSize - 1) | defaultDataSize - 1 - getRandomFile(defaultDataSize) | new BlobRange(0, defaultDataSize - 1) | defaultDataSize - 1 - getRandomFile(defaultDataSize) | new BlobRange(0, 10L * 1024 * 1024 * 1024) | defaultDataSize + file | range | dataSize + getRandomFile(defaultDataSize) | new BlobRange().withCount(defaultDataSize) | defaultDataSize + getRandomFile(defaultDataSize) | new BlobRange().withOffset(1).withCount(defaultDataSize - 1) | defaultDataSize - 1 + getRandomFile(defaultDataSize) | new BlobRange().withCount(defaultDataSize - 1) | defaultDataSize - 1 + getRandomFile(defaultDataSize) | new BlobRange().withCount(10L * 1024 * 1024 * 1024) | defaultDataSize } def "Download file count null"() { setup: - bu.upload(defaultFlowable, defaultDataSize, null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() File outFile = getRandomFile(0) def outChannel = AsynchronousFileChannel.open(outFile.toPath(), StandardOpenOption.WRITE, StandardOpenOption.READ) when: - TransferManager.downloadBlobToFile(outChannel, bu, new BlobRange(0, null), null) + TransferManager.downloadBlobToFile(outChannel, bu, new BlobRange(), null) .blockingGet() then: @@ -431,12 +438,13 @@ class TransferManagerTest extends APISpec { match = setupBlobMatchCondition(bu, match) leaseID = setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: - TransferManager.downloadBlobToFile(outChannel, bu, null, new TransferManager.DownloadFromBlobOptions( + TransferManager.downloadBlobToFile(outChannel, bu, null, new TransferManagerDownloadFromBlobOptions( null, null, bac, null, null)).blockingGet() then: @@ -468,13 +476,14 @@ class TransferManagerTest extends APISpec { noneMatch = setupBlobMatchCondition(bu, noneMatch) setupBlobLeaseCondition(bu, leaseID) - BlobAccessConditions bac = new BlobAccessConditions( - new HTTPAccessConditions(modified, unmodified, match, noneMatch), new LeaseAccessConditions(leaseID), - null, null) + BlobAccessConditions bac = new BlobAccessConditions().withModifiedAccessConditions( + new ModifiedAccessConditions().withIfModifiedSince(modified).withIfUnmodifiedSince(unmodified) + .withIfMatch(match).withIfNoneMatch(noneMatch)) + .withLeaseAccessConditions(new LeaseAccessConditions().withLeaseId(leaseID)) when: TransferManager.downloadBlobToFile(outChannel, bu, null, - new TransferManager.DownloadFromBlobOptions(null, null, bac, null, + new TransferManagerDownloadFromBlobOptions(null, null, bac, null, null)).blockingGet() then: @@ -494,7 +503,7 @@ class TransferManagerTest extends APISpec { def "Download file etag lock"() { setup: bu.upload(Flowable.just(getRandomData(1 * 1024 * 1024)), 1 * 1024 * 1024, null, null, - null).blockingGet() + null, null).blockingGet() def outChannel = AsynchronousFileChannel.open(getRandomFile(0).toPath(), StandardOpenOption.WRITE, StandardOpenOption.READ) @@ -505,7 +514,7 @@ class TransferManagerTest extends APISpec { */ def success = false TransferManager.downloadBlobToFile(outChannel, bu, null, - new TransferManager.DownloadFromBlobOptions(1024, null, null, + new TransferManagerDownloadFromBlobOptions(1024, null, null, null, null)) .subscribe( new Consumer() { @@ -528,7 +537,7 @@ class TransferManagerTest extends APISpec { sleep(500) // Give some time for the download request to start. - bu.upload(defaultFlowable, defaultDataSize, null, null, null).blockingGet() + bu.upload(defaultFlowable, defaultDataSize, null, null, null, null).blockingGet() sleep(1000) // Allow time for the upload operation @@ -548,12 +557,12 @@ class TransferManagerTest extends APISpec { .blockingGet() def outChannel = AsynchronousFileChannel.open(getRandomFile(0).toPath(), StandardOpenOption.WRITE, StandardOpenOption.READ) - def retryReaderOptions = new RetryReaderOptions() - retryReaderOptions.maxRetryRequests = retries + def reliableDownloadOptions = new ReliableDownloadOptions() + reliableDownloadOptions.withMaxRetryRequests(retries) when: - TransferManager.downloadBlobToFile(outChannel, bu, null, new TransferManager.DownloadFromBlobOptions( - blockSize, null, null, parallelism, retryReaderOptions)).blockingGet() + TransferManager.downloadBlobToFile(outChannel, bu, null, new TransferManagerDownloadFromBlobOptions( + blockSize, null, null, parallelism, reliableDownloadOptions)).blockingGet() then: compareFiles(channel, 0, channel.size(), outChannel) @@ -591,7 +600,7 @@ class TransferManagerTest extends APISpec { @Unroll def "Download options fail"() { when: - new TransferManager.DownloadFromBlobOptions(blockSize, null, null, parallelism, + new TransferManagerDownloadFromBlobOptions(blockSize, null, null, parallelism, null) then: diff --git a/src/test/java/com/microsoft/azure/storage/RetryReaderMockFlowable.java b/src/test/java/com/microsoft/azure/storage/blob/DownloadResponseMockFlowable.java similarity index 71% rename from src/test/java/com/microsoft/azure/storage/RetryReaderMockFlowable.java rename to src/test/java/com/microsoft/azure/storage/blob/DownloadResponseMockFlowable.java index 78bb43057bd6..f5f9cf8f4297 100644 --- a/src/test/java/com/microsoft/azure/storage/RetryReaderMockFlowable.java +++ b/src/test/java/com/microsoft/azure/storage/blob/DownloadResponseMockFlowable.java @@ -13,28 +13,24 @@ * limitations under the License. */ -package com.microsoft.azure.storage; +package com.microsoft.azure.storage.blob; -import com.microsoft.azure.storage.blob.ETag; -import com.microsoft.azure.storage.blob.RetryReader; +import java.io.IOException; +import java.nio.ByteBuffer; + +import com.microsoft.azure.storage.APISpec; import com.microsoft.azure.storage.blob.models.BlobDownloadHeaders; +import com.microsoft.azure.storage.blob.models.BlobDownloadResponse; import com.microsoft.azure.storage.blob.models.StorageErrorException; -import com.microsoft.rest.v2.RestResponse; import com.microsoft.rest.v2.http.HttpHeaders; import com.microsoft.rest.v2.http.HttpResponse; -import io.netty.channel.ChannelException; import io.reactivex.Flowable; import io.reactivex.Single; import org.reactivestreams.Subscriber; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.nio.ByteBuffer; -import java.nio.channels.ClosedChannelException; import java.util.HashMap; -import java.util.concurrent.TimeoutException; -public class RetryReaderMockFlowable extends Flowable { +public class DownloadResponseMockFlowable extends Flowable { public static final int RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK = 0; @@ -46,19 +42,15 @@ public class RetryReaderMockFlowable extends Flowable { public static final int RR_TEST_SCENARIO_NON_RETRYABLE_ERROR = 4; - public static final int RR_TEST_SCENARIO_ERROR_GETTER_INITIAL = 5; - public static final int RR_TEST_SCENARIO_ERROR_GETTER_MIDDLE = 6; - public static final int RR_TEST_SCENARIO_SUCCESSFUL_INITIAL_RESPONSE = 7; - public static final int RR_TEST_SCENARIO_INFO_TEST = 8; private int scenario; private int tryNumber; - private RetryReader.HTTPGetterInfo info; + private HTTPGetterInfo info; private ByteBuffer scenarioData; @@ -70,7 +62,7 @@ public int getTryNumber() { return this.tryNumber; } - public RetryReaderMockFlowable(int scenario) { + public DownloadResponseMockFlowable(int scenario) { this.scenario = scenario; switch(this.scenario) { case RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK: @@ -79,8 +71,6 @@ public RetryReaderMockFlowable(int scenario) { case RR_TEST_SCENARIO_SUCCESSFUL_MULTI_CHUNK: // Fall through case RR_TEST_SCENARIO_SUCCESSFUL_STREAM_FAILURES: - // Fall through - case RR_TEST_SCENARIO_SUCCESSFUL_INITIAL_RESPONSE: this.scenarioData = APISpec.getRandomData(1024); } } @@ -106,8 +96,8 @@ protected void subscribeActual(Subscriber s) { case RR_TEST_SCENARIO_SUCCESSFUL_STREAM_FAILURES: if (this.tryNumber <= 3) { // tryNumber is 1 indexed, so we have to sub 1. - if (this.info.offset != (this.tryNumber-1)*256 || - this.info.count != this.scenarioData.remaining() - (this.tryNumber-1) * 256) { + if (this.info.offset() != (this.tryNumber-1)*256 || + this.info.count() != this.scenarioData.remaining() - (this.tryNumber-1) * 256) { s.onError(new IllegalArgumentException("Info values are incorrect.")); return; } @@ -115,11 +105,11 @@ protected void subscribeActual(Subscriber s) { toSend.position((this.tryNumber-1)*256); toSend.limit(this.tryNumber*256); s.onNext(toSend); - s.onError(new ChannelException()); + s.onError(new IOException()); break; } - if (this.info.offset != (this.tryNumber-1)*256 || - this.info.count != this.scenarioData.remaining() - (this.tryNumber-1) * 256) { + if (this.info.offset() != (this.tryNumber-1)*256 || + this.info.count() != this.scenarioData.remaining() - (this.tryNumber-1) * 256) { s.onError(new IllegalArgumentException("Info values are incorrect.")); return; } @@ -131,7 +121,7 @@ protected void subscribeActual(Subscriber s) { break; case RR_TEST_SCENARIO_MAX_RETRIES_EXCEEDED: - s.onError(new SocketTimeoutException()); + s.onError(new IOException()); break; case RR_TEST_SCENARIO_NON_RETRYABLE_ERROR: @@ -139,27 +129,28 @@ protected void subscribeActual(Subscriber s) { break; case RR_TEST_SCENARIO_ERROR_GETTER_MIDDLE: - /* - We return a retryable error here so we have to invoke the getter, which will throw an error in this - case. - */ - s.onError(new ChannelException()); - break; - - case RR_TEST_SCENARIO_SUCCESSFUL_INITIAL_RESPONSE: - s.onNext(this.scenarioData.duplicate()); - s.onComplete(); + switch (this.tryNumber) { + case 1: + /* + We return a retryable error here so we have to invoke the getter, which will throw an error in + this case. + */ + s.onError(new IOException()); + break; + default: + s.onError(new IllegalArgumentException("Retried after getter error.")); + } break; case RR_TEST_SCENARIO_INFO_TEST: switch (this.tryNumber) { case 1: // Test the value of info when getting the initial response. - s.onError(new TimeoutException()); + s.onError(new IOException()); break; case 2: // Test the value of info when getting an intermediate response. - s.onError(new SocketException()); + s.onError(new IOException()); break; case 3: // All calls to getter checked. Exit. This test does not check for data. @@ -173,26 +164,27 @@ protected void subscribeActual(Subscriber s) { } } - public Single>> getter(RetryReader.HTTPGetterInfo info) { + public Single getter(HTTPGetterInfo info) { this.tryNumber++; this.info = info; - RestResponse> response = - new RestResponse<>(null,200, new BlobDownloadHeaders(), new HashMap<>(), this); + BlobDownloadResponse rawResponse = + new BlobDownloadResponse(null, 200, new BlobDownloadHeaders(), new HashMap<>(), this); + DownloadResponse response = new DownloadResponse(rawResponse, info, this::getter); switch(this.scenario) { - case RR_TEST_SCENARIO_ERROR_GETTER_INITIAL: - throw new Error("Getter error", new ClosedChannelException()); case RR_TEST_SCENARIO_ERROR_GETTER_MIDDLE: switch (this.tryNumber) { case 1: return Single.just(response); case 2: - // This validates that we don't retry in the getter even if it's an error from the service. - throw new Error("GetterError", - new StorageErrorException("Message", new HttpResponse() { + /* + This validates that we don't retry in the getter even if it's a retryable error from the + service. + */ + throw new StorageErrorException("Message", new HttpResponse() { @Override public int statusCode() { - return 0; + return 500; } @Override @@ -219,13 +211,13 @@ public Single bodyAsByteArray() { public Single bodyAsString() { return null; } - })); + }); default: throw new IllegalArgumentException("Retried after error in getter"); } case RR_TEST_SCENARIO_INFO_TEST: // We also test that the info is updated in RR_TEST_SCENARIO_SUCCESSFUL_STREAM_FAILURES. - if (info.count != 10 || info.offset != 20 || !info.eTag.equals(new ETag("etag"))) { + if (info.count() != 10 || info.offset() != 20 || !info.eTag().equals("etag")) { throw new IllegalArgumentException("Info values incorrect"); } return Single.just(response); diff --git a/src/test/java/com/microsoft/azure/storage/blob/DownloadResponseTest.groovy b/src/test/java/com/microsoft/azure/storage/blob/DownloadResponseTest.groovy new file mode 100644 index 000000000000..369b911a7ca4 --- /dev/null +++ b/src/test/java/com/microsoft/azure/storage/blob/DownloadResponseTest.groovy @@ -0,0 +1,180 @@ +/* + * 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.APISpec +import com.microsoft.azure.storage.blob.models.StorageErrorException +import com.microsoft.rest.v2.util.FlowableUtil +import io.reactivex.Flowable +import spock.lang.Unroll + +class DownloadResponseTest extends APISpec { + BlockBlobURL bu + + def setup() { + bu = cu.createBlockBlobURL(generateBlobName()) + bu.upload(Flowable.just(defaultData), defaultText.length(), null, null, null, null).blockingGet() + } + + /* + This shouldn't really be different from anything else we're doing in the other tests. Just a sanity check against + a real use case. + */ + + def "Network call"() { + expect: + FlowableUtil.collectBytesInBuffer(bu.download(null, null, false, null).blockingGet().body(null)) + .blockingGet() == defaultData + } + + @Unroll + def "Successful"() { + setup: + DownloadResponseMockFlowable flowable = new DownloadResponseMockFlowable(scenario) + def info = new HTTPGetterInfo() + info.withOffset(0) + .withCount(flowable.getScenarioData().remaining()) + .withETag("etag") + + def options = new ReliableDownloadOptions() + options.withMaxRetryRequests(5) + + def mockRawResponse = flowable.getter(info).blockingGet().rawResponse() + + when: + DownloadResponse response = new DownloadResponse(mockRawResponse, info, { HTTPGetterInfo newInfo -> + flowable.getter(newInfo) + }) + + then: + FlowableUtil.collectBytesInBuffer(response.body(options)).blockingGet() == flowable.getScenarioData() + flowable.getTryNumber() == tryNumber + + + where: + scenario | tryNumber | provideInitialResponse + DownloadResponseMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK | 1 | false + DownloadResponseMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_MULTI_CHUNK | 1 | false + DownloadResponseMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_STREAM_FAILURES | 4 | false + } + + @Unroll + def "Failure"() { + setup: + def flowable = new DownloadResponseMockFlowable(scenario) + + def options = new ReliableDownloadOptions() + .withMaxRetryRequests(5) + + def info = new HTTPGetterInfo().withETag("etag") + def mockRawResponse = flowable.getter(info).blockingGet().rawResponse() + + when: + DownloadResponse response = new DownloadResponse(mockRawResponse, info, { HTTPGetterInfo newInfo -> + flowable.getter(newInfo) + }) + response.body(options).blockingSubscribe() + + then: + def e = thrown(Throwable) // Blocking subscribe will sometimes wrap the IOException in a RuntimeException. + if (e.getCause() != null) { + e = e.getCause() + } + exceptionType.isInstance(e) + flowable.getTryNumber() == tryNumber + + /* + tryNumber is 7 because the initial request is the first try, then it will fail when retryCount>maxRetryCount, + which is when retryCount=6 and therefore tryNumber=7 + */ + where: + scenario | exceptionType | tryNumber + DownloadResponseMockFlowable.RR_TEST_SCENARIO_MAX_RETRIES_EXCEEDED | IOException | 7 + DownloadResponseMockFlowable.RR_TEST_SCENARIO_NON_RETRYABLE_ERROR | Exception | 1 + DownloadResponseMockFlowable.RR_TEST_SCENARIO_ERROR_GETTER_MIDDLE | StorageErrorException | 2 + } + + @Unroll + def "Info null IA"() { + setup: + def flowable = new DownloadResponseMockFlowable( + DownloadResponseMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK) + + when: + new DownloadResponse(flowable.getter(info).blockingGet().rawResponse(), info, + { HTTPGetterInfo newInfo -> + flowable.getter(newInfo) + }) + + + then: + thrown(IllegalArgumentException) + + where: + info | _ + null | _ + new HTTPGetterInfo().withETag(null) | _ + } + + def "Options IA"() { + when: + new ReliableDownloadOptions().withMaxRetryRequests(-1) + + then: + thrown(IllegalArgumentException) + } + + def "Getter IA"() { + setup: + def flowable = new DownloadResponseMockFlowable(DownloadResponseMockFlowable.RR_TEST_SCENARIO_SUCCESSFUL_ONE_CHUNK) + + when: + def response = new DownloadResponse(flowable.getter(new HTTPGetterInfo()).blockingGet() + .rawResponse(), new HTTPGetterInfo().withETag("etag"), null) + response.body(null).blockingSubscribe() + + then: + thrown(IllegalArgumentException) + } + + def "Info"() { + setup: + def flowable = new DownloadResponseMockFlowable(DownloadResponseMockFlowable.RR_TEST_SCENARIO_INFO_TEST) + def info = new HTTPGetterInfo() + info.withOffset(20) + info.withCount(10) + info.withETag("etag") + def options = new ReliableDownloadOptions() + options.withMaxRetryRequests(5) + + when: + def response = new DownloadResponse(flowable.getter(info).blockingGet().rawResponse(), info, + { HTTPGetterInfo newInfo -> + return flowable.getter(newInfo) + }) + response.body(options).blockingSubscribe() + + then: + flowable.tryNumber == 3 + } + + def "Info count IA"() { + when: + new HTTPGetterInfo().withCount(-1) + + then: + thrown(IllegalArgumentException) + } +} diff --git a/src/test/java/com/microsoft/azure/storage/blob/HelperTest.groovy b/src/test/java/com/microsoft/azure/storage/blob/HelperTest.groovy index 802f480f4413..006d19165c58 100644 --- a/src/test/java/com/microsoft/azure/storage/blob/HelperTest.groovy +++ b/src/test/java/com/microsoft/azure/storage/blob/HelperTest.groovy @@ -19,7 +19,6 @@ import com.microsoft.azure.storage.APISpec import com.microsoft.azure.storage.blob.models.AccessPolicy import com.microsoft.azure.storage.blob.models.SignedIdentifier import com.microsoft.azure.storage.blob.models.StorageErrorCode -import com.microsoft.azure.storage.blob.models.StorageServiceProperties import spock.lang.Unroll import java.time.OffsetDateTime @@ -29,7 +28,7 @@ class HelperTest extends APISpec { def "responseError"() { when: - cu.listBlobsFlatSegment("garbage", null).blockingGet() + cu.listBlobsFlatSegment("garbage", null, null).blockingGet() then: def e = thrown(StorageException) @@ -42,7 +41,7 @@ class HelperTest extends APISpec { @Unroll def "Blob range"() { expect: - new BlobRange(offset, count).toString() == result + new BlobRange().withOffset(offset).withCount(count).toString() == result where: offset | count || result @@ -53,7 +52,7 @@ class HelperTest extends APISpec { @Unroll def "Blob range IA"() { when: - new BlobRange(offset, count) + new BlobRange().withOffset(offset).withCount(count) then: thrown(IllegalArgumentException) @@ -69,43 +68,42 @@ class HelperTest extends APISpec { def containerName = generateContainerName() def blobName = generateBlobName() def cu = primaryServiceURL.createContainerURL(containerName) - cu.create(null, null).blockingGet() + cu.create(null, null, null).blockingGet() def v = new ServiceSASSignatureValues() def p = new BlobSASPermission() - p.read = true - p.write = true - p.create = true - p.delete = true - p.add = true - v.permissions = p.toString(); - v.startTime = OffsetDateTime.now().minusDays(1) - v.expiryTime = OffsetDateTime.now().plusDays(1) - v.containerName = containerName - v.blobName = blobName + .withRead(true) + .withWrite(true) + .withCreate(true) + .withDelete(true) + .withAdd(true) + v.withPermissions(p.toString()) + .withStartTime(OffsetDateTime.now().minusDays(1)) + .withExpiryTime(OffsetDateTime.now().plusDays(1)) + .withContainerName(containerName) + .withBlobName(blobName) def ipR = new IPRange() - ipR.ipMin = "0.0.0.0" - ipR.ipMax = "255.255.255.255" - v.ipRange = ipR - v.protocol = SASProtocol.HTTPS_ONLY - v.cacheControl = "cache" - v.contentDisposition = "disposition" - v.contentEncoding = "encoding" - v.contentLanguage = "language" - v.contentType = "type" + .withIpMin("0.0.0.0") + .withIpMax("255.255.255.255") + v.withIpRange(ipR) + .withProtocol(SASProtocol.HTTPS_ONLY) + .withCacheControl("cache") + .withContentDisposition("disposition") + .withContentEncoding("encoding") + .withContentLanguage("language") + .withContentType("type") when: def parts = URLParser.parse(cu.createBlobURL(blobName).toURL()) - parts.sasQueryParameters = v.generateSASQueryParameters(primaryCreds) - parts.scheme = "https" + parts.withSasQueryParameters(v.generateSASQueryParameters(primaryCreds)).withScheme("https") def bu = new AppendBlobURL(parts.toURL(), StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions())) then: - bu.create(null, null, null).blockingGet() + bu.create(null, null, null, null).blockingGet() and: - def properties = bu.getProperties(null).blockingGet().headers() + def properties = bu.getProperties(null, null).blockingGet().headers() then: properties.cacheControl() == "cache" @@ -115,48 +113,48 @@ class HelperTest extends APISpec { properties.contentType() == "type" } - def "serviceSASSignatureValues network test container"(){ + def "serviceSASSignatureValues network test container"() { setup: def containerName = generateContainerName() def cu = primaryServiceURL.createContainerURL(containerName) - cu.create(null, null).blockingGet() + cu.create(null, null, null).blockingGet() def id = new SignedIdentifier().withId("0000").withAccessPolicy(new AccessPolicy().withPermission("racwdl") .withExpiry(OffsetDateTime.now().plusDays(1))) - cu.setAccessPolicy(null, Arrays.asList(id), null).blockingGet() + cu.setAccessPolicy(null, Arrays.asList(id), null, null).blockingGet() // Check id field def v = new ServiceSASSignatureValues() - v.identifier = "0000" - v.containerName = containerName - v.protocol = SASProtocol.HTTPS_ONLY + .withIdentifier("0000") + .withContainerName(containerName) + .withProtocol(SASProtocol.HTTPS_ONLY) // Check containerSASPermissions def v2 = new ServiceSASSignatureValues() def p = new ContainerSASPermission() - p.read = true - p.write = true - p.create = true - p.delete = true - p.add = true - p.list = true - v2.permissions = p.toString(); - v2.expiryTime = OffsetDateTime.now().plusDays(1) - v2.containerName = containerName + .withRead(true) + .withWrite(true) + .withCreate(true) + .withDelete(true) + .withAdd(true) + .withList(true) + v2.withPermissions(p.toString()) + .withExpiryTime(OffsetDateTime.now().plusDays(1)) + .withContainerName(containerName) when: def parts = URLParser.parse(cu.toURL()) - parts.sasQueryParameters = v.generateSASQueryParameters(primaryCreds) - parts.scheme = "https" + .withSasQueryParameters(v.generateSASQueryParameters(primaryCreds)) + .withScheme("https") def cuSAS = new ContainerURL(parts.toURL(), StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions())) - parts.sasQueryParameters = v2.generateSASQueryParameters(primaryCreds) + parts.withSasQueryParameters(v2.generateSASQueryParameters(primaryCreds)) def cuSAS2 = new ContainerURL(parts.toURL(), StorageURL.createPipeline(new AnonymousCredentials(), new PipelineOptions())) then: - cuSAS.listBlobsFlatSegment(null, null).blockingGet() - cuSAS2.listBlobsFlatSegment(null, null).blockingGet() + cuSAS.listBlobsFlatSegment(null, null, null).blockingGet() + cuSAS2.listBlobsFlatSegment(null, null, null).blockingGet() notThrown(StorageException) } @@ -165,35 +163,36 @@ class HelperTest extends APISpec { values are handled correctly. We will validate the whole SAS with service calls as well as correct serialization of individual parts later. */ + @Unroll def "serviceSasSignatures string to sign"() { when: def v = new ServiceSASSignatureValues() if (permissions != null) { def p = new BlobSASPermission() - p.read = true - v.permissions = p.toString(); + p.withRead(true) + v.withPermissions(p.toString()) } - v.startTime = startTime - v.expiryTime = expiryTime - v.containerName = "c" + v.withStartTime(startTime) + .withExpiryTime(expiryTime) + .withContainerName("c") if (ipRange != null) { def ipR = new IPRange() - ipR.ipMin = "ip" - v.ipRange = ipR + ipR.withIpMin("ip") + v.withIpRange(ipR) } - v.identifier = identifier - v.protocol = protocol - v.cacheControl = cacheControl - v.contentDisposition = disposition - v.contentEncoding = encoding - v.contentLanguage = language - v.contentType = type + v.withIdentifier(identifier) + .withProtocol(protocol) + .withCacheControl(cacheControl) + .withContentDisposition(disposition) + .withContentEncoding(encoding) + .withContentLanguage(language) + .withContentType(type) def token = v.generateSASQueryParameters(primaryCreds) then: - token.signature == primaryCreds.computeHmac256(expectedStringToSign) + token.signature() == primaryCreds.computeHmac256(expectedStringToSign) /* We don't test the blob or containerName properties because canonicalized resource is always added as at least @@ -219,15 +218,15 @@ class HelperTest extends APISpec { def "serviceSASSignatureValues canonicalizedResource"() { setup: def v = new ServiceSASSignatureValues() - v.containerName = containerName - v.blobName = blobName + .withContainerName(containerName) + .withBlobName(blobName) when: def token = v.generateSASQueryParameters(primaryCreds) then: - token.signature == primaryCreds.computeHmac256(expectedStringToSign) - token.getResource() == expectedResource + token.signature() == primaryCreds.computeHmac256(expectedStringToSign) + token.resource() == expectedResource where: containerName | blobName || expectedResource | expectedStringToSign @@ -240,8 +239,8 @@ class HelperTest extends APISpec { def "serviceSasSignatureValues IA"() { setup: def v = new ServiceSASSignatureValues() - v.containerName = containerName - v.version = version + .withContainerName(containerName) + .withVersion(version) when: v.generateSASQueryParameters(creds) @@ -261,11 +260,11 @@ class HelperTest extends APISpec { def "BlobSASPermissions toString"() { setup: def perms = new BlobSASPermission() - perms.read = read - perms.write = write - perms.delete = delete - perms.create = create - perms.add = add + .withRead(read) + .withWrite(write) + .withDelete(delete) + .withCreate(create) + .withAdd(add) expect: perms.toString() == expectedString @@ -286,11 +285,11 @@ class HelperTest extends APISpec { def perms = BlobSASPermission.parse(permString) then: - perms.read == read - perms.write == write - perms.delete == delete - perms.create == create - perms.add == add + perms.read() == read + perms.write() == write + perms.delete() == delete + perms.create() == create + perms.add() == add where: permString || read | write | delete | create | add @@ -315,12 +314,12 @@ class HelperTest extends APISpec { def "ContainerSASPermissions toString"() { setup: def perms = new ContainerSASPermission() - perms.read = read - perms.write = write - perms.delete = delete - perms.create = create - perms.add = add - perms.list = list + .withRead(read) + .withWrite(write) + .withDelete(delete) + .withCreate(create) + .withAdd(add) + .withList(list) expect: perms.toString() == expectedString @@ -342,12 +341,12 @@ class HelperTest extends APISpec { def perms = ContainerSASPermission.parse(permString) then: - perms.read == read - perms.write == write - perms.delete == delete - perms.create == create - perms.add == add - perms.list == list + perms.read() == read + perms.write() == write + perms.delete() == delete + perms.create() == create + perms.add() == add + perms.list() == list where: permString || read | write | delete | create | add | list @@ -373,8 +372,8 @@ class HelperTest extends APISpec { def "IPRange toString"() { setup: def ip = new IPRange() - ip.ipMin = min - ip.ipMax = max + .withIpMin(min) + .withIpMax(max) expect: ip.toString() == expectedString @@ -392,8 +391,8 @@ class HelperTest extends APISpec { def ip = IPRange.parse(rangeStr) then: - ip.ipMin == min - ip.ipMax == max + ip.ipMin() == min + ip.ipMax() == max where: rangeStr || min | max @@ -424,23 +423,23 @@ class HelperTest extends APISpec { when: def v = new AccountSASSignatureValues() def p = new AccountSASPermission() - p.read = true - v.permissions = p.toString(); - v.services = "b" - v.resourceTypes = "o" - v.startTime = startTime - v.expiryTime = OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC) + .withRead(true) + v.withPermissions(p.toString()) + .withServices("b") + .withResourceTypes("o") + .withStartTime(startTime) + .withExpiryTime(OffsetDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) if (ipRange != null) { def ipR = new IPRange() - ipR.ipMin = "ip" - v.ipRange = ipR + ipR.withIpMin("ip") + v.withIpRange(ipR) } - v.protocol = protocol + v.withProtocol(protocol) def token = v.generateSASQueryParameters(primaryCreds) then: - token.signature == primaryCreds.computeHmac256(expectedStringToSign) + token.signature() == primaryCreds.computeHmac256(expectedStringToSign) where: startTime | ipRange | protocol || expectedStringToSign @@ -453,11 +452,11 @@ class HelperTest extends APISpec { def "accountSasSignatureValues IA"() { setup: def v = new AccountSASSignatureValues() - v.permissions = permissions - v.services = service - v.resourceTypes = resourceType - v.expiryTime = expiryTime - v.version = version + .withPermissions(permissions) + .withServices(service) + .withResourceTypes(resourceType) + .withExpiryTime(expiryTime) + .withVersion(version) when: v.generateSASQueryParameters(creds) @@ -480,14 +479,14 @@ class HelperTest extends APISpec { def "AccountSASPermissions toString"() { setup: def perms = new AccountSASPermission() - perms.read = read - perms.write = write - perms.delete = delete - perms.list = list - perms.add = add - perms.create = create - perms.update = update - perms.processMessages = process + perms.withRead(read) + .withWrite(write) + .withDelete(delete) + .withList(list) + .withAdd(add) + .withCreate(create) + .withUpdate(update) + .withProcessMessages(process) expect: perms.toString() == expectedString @@ -511,14 +510,14 @@ class HelperTest extends APISpec { def perms = AccountSASPermission.parse(permString) then: - perms.read == read - perms.write == write - perms.delete == delete - perms.list == list - perms.add == add - perms.create == create - perms.update == update - perms.processMessages == process + perms.read() == read + perms.write() == write + perms.delete() == delete + perms.list() == list + perms.add() == add + perms.create() == create + perms.update() == update + perms.processMessages() == process where: permString || read | write | delete | list | add | create | update | process @@ -546,9 +545,9 @@ class HelperTest extends APISpec { def "AccountSASResourceType toString"() { setup: def resourceTypes = new AccountSASResourceType() - resourceTypes.service = service - resourceTypes.container = container - resourceTypes.object = object + .withService(service) + .withContainer(container) + .withObject(object) expect: resourceTypes.toString() == expectedString @@ -567,9 +566,9 @@ class HelperTest extends APISpec { def resourceTypes = AccountSASResourceType.parse(resourceTypeString) then: - resourceTypes.service == service - resourceTypes.container == container - resourceTypes.object == object + resourceTypes.service() == service + resourceTypes.container() == container + resourceTypes.object() == object where: resourceTypeString || service | container | object @@ -591,15 +590,15 @@ class HelperTest extends APISpec { def "BlobURLParts"() { setup: def parts = new BlobURLParts() - parts.scheme = "http" - parts.host = "host" - parts.containerName = "container" - parts.blobName = "blob" - parts.snapshot = "snapshot" + parts.withScheme("http") + .withHost("host") + .withContainerName("container") + .withBlobName("blob") + .withSnapshot("snapshot") def sasValues = new ServiceSASSignatureValues() - sasValues.permissions = "r" - sasValues.containerName = "container" - parts.sasQueryParameters = sasValues.generateSASQueryParameters(primaryCreds) + .withPermissions("r") + .withContainerName("container") + parts.withSasQueryParameters(sasValues.generateSASQueryParameters(primaryCreds)) when: def splitParts = parts.toURL().toString().split("\\?") @@ -618,15 +617,15 @@ class HelperTest extends APISpec { def parts = URLParser.parse(new URL("http://host/container/blob?snapshot=snapshot&sv=2018-03-28&sr=c&sp=r&sig=Ee%2BSodSXamKSzivSdRTqYGh7AeMVEk3wEoRZ1yzkpSc%3D")) then: - parts.scheme == "http" - parts.host == "host" - parts.containerName == "container" - parts.blobName == "blob" - parts.snapshot == "snapshot" - parts.sasQueryParameters.getPermissions() == "r" - parts.sasQueryParameters.getVersion() == Constants.HeaderConstants.TARGET_STORAGE_VERSION - parts.sasQueryParameters.getResource() == "c" - parts.sasQueryParameters.getSignature() == + parts.scheme() == "http" + parts.host() == "host" + parts.containerName() == "container" + parts.blobName() == "blob" + parts.snapshot() == "snapshot" + parts.sasQueryParameters().permissions() == "r" + parts.sasQueryParameters().version() == Constants.HeaderConstants.TARGET_STORAGE_VERSION + parts.sasQueryParameters().resource() == "c" + parts.sasQueryParameters().signature() == Utility.safeURLDecode("Ee%2BSodSXamKSzivSdRTqYGh7AeMVEk3wEoRZ1yzkpSc%3D") } } diff --git a/src/test/java/com/microsoft/azure/storage/blob/LoggingTest.groovy b/src/test/java/com/microsoft/azure/storage/blob/LoggingTest.groovy index 252b95c10dc8..d2071e66f0ab 100644 --- a/src/test/java/com/microsoft/azure/storage/blob/LoggingTest.groovy +++ b/src/test/java/com/microsoft/azure/storage/blob/LoggingTest.groovy @@ -26,18 +26,6 @@ import io.reactivex.Single import spock.lang.Unroll class LoggingTest extends APISpec { - - /* - This method returns a stub of an HttpResponse. We know that the logger only looks at the status code, so we stub - a response that always returns a given value for the status code. We never care about the number or nature of - interactions with this stub. - */ - def getStubResponse(int code) { - return Stub(HttpResponse) { - statusCode() >> code - } - } - /* This method returns a mock of an HttpPipelineLogger. We always want to return the same value for a given run. A mock also allows for defining the number and kind of interactions that the unit under test has with this mocked object. @@ -245,13 +233,13 @@ class LoggingTest extends APISpec { setup: def logger = getMockLogger(HttpPipelineLogLevel.INFO) def po = new PipelineOptions() - po.logger = logger + po.withLogger(logger) cu = primaryServiceURL.createContainerURL(generateContainerName()) cu = new ContainerURL(cu.toURL(), StorageURL.createPipeline(primaryCreds, po)) when: - cu.create(null, null).blockingGet() + cu.create(null, null, null).blockingGet() then: 2 * logger.log(*_) diff --git a/src/test/java/com/microsoft/azure/storage/blob/RequestRetryTestFactory.java b/src/test/java/com/microsoft/azure/storage/blob/RequestRetryTestFactory.java index 907feb6feccf..d16a61172efb 100644 --- a/src/test/java/com/microsoft/azure/storage/blob/RequestRetryTestFactory.java +++ b/src/test/java/com/microsoft/azure/storage/blob/RequestRetryTestFactory.java @@ -16,10 +16,7 @@ package com.microsoft.azure.storage.blob; import com.microsoft.azure.storage.blob.models.StorageErrorException; -import com.microsoft.rest.v2.http.HttpHeaders; -import com.microsoft.rest.v2.http.HttpRequest; -import com.microsoft.rest.v2.http.HttpResponse; -import com.microsoft.rest.v2.http.UrlBuilder; +import com.microsoft.rest.v2.http.*; import com.microsoft.rest.v2.policy.RequestPolicy; import com.microsoft.rest.v2.policy.RequestPolicyFactory; import com.microsoft.rest.v2.policy.RequestPolicyOptions; @@ -29,6 +26,7 @@ import io.reactivex.Single; import io.reactivex.SingleObserver; +import java.io.IOException; import java.net.MalformedURLException; import java.net.SocketException; import java.net.SocketTimeoutException; @@ -58,6 +56,8 @@ public class RequestRetryTestFactory implements RequestPolicyFactory { public static final int RETRY_TEST_SCENARIO_TRY_TIMEOUT = 8; + public static final int RETRY_TEST_SCENARIO_NON_REPLAYABLE_FLOWABLE = 9; + // Cancelable public static final String RETRY_TEST_PRIMARY_HOST = "PrimaryDC"; @@ -126,7 +126,7 @@ private final class RetryTestPolicy implements RequestPolicy { @Override public Single sendAsync(HttpRequest request) { this.factory.tryNumber++; - if (this.factory.tryNumber > this.factory.options.getMaxTries()) { + if (this.factory.tryNumber > this.factory.options.maxTries()) { throw new IllegalArgumentException("Try number has exceeded max tries"); } @@ -235,14 +235,10 @@ public Single sendAsync(HttpRequest request) { case RETRY_TEST_SCENARIO_NETWORK_ERROR: switch (this.factory.tryNumber) { case 1: - return Single.error(new ChannelException()); + // fall through case 2: - return Single.error(new ClosedChannelException()); + return Single.error(new IOException()); case 3: - return Single.error(new SocketException()); - case 4: - return Single.error(new SocketTimeoutException()); - case 5: return RETRY_TEST_OK_RESPONSE; default: throw new IllegalArgumentException("Continued retrying after success."); @@ -251,11 +247,11 @@ public Single sendAsync(HttpRequest request) { case RETRY_TEST_SCENARIO_TRY_TIMEOUT: switch (this.factory.tryNumber) { case 1: - return RETRY_TEST_OK_RESPONSE.delay(options.getTryTimeout() + 1, TimeUnit.SECONDS); + return RETRY_TEST_OK_RESPONSE.delay(options.tryTimeout() + 1, TimeUnit.SECONDS); case 2: - return RETRY_TEST_OK_RESPONSE.delay(options.getTryTimeout() + 1, TimeUnit.SECONDS); + return RETRY_TEST_OK_RESPONSE.delay(options.tryTimeout() + 1, TimeUnit.SECONDS); case 3: - return RETRY_TEST_OK_RESPONSE.delay(options.getTryTimeout() - 1, TimeUnit.SECONDS); + return RETRY_TEST_OK_RESPONSE.delay(options.tryTimeout() - 1, TimeUnit.SECONDS); default: throw new IllegalArgumentException("Continued retrying after success"); } @@ -309,6 +305,16 @@ public Single sendAsync(HttpRequest request) { default: throw new IllegalArgumentException("Retries continued after success."); } + + case RETRY_TEST_SCENARIO_NON_REPLAYABLE_FLOWABLE: + switch (this.factory.tryNumber) { + case 1: + return RETRY_TEST_TEMPORARY_ERROR_RESPONSE; + case 2: + return Single.error(new UnexpectedLengthException("Unexpected length", 5, 6)); + default: + throw new IllegalArgumentException("Retries continued on non retryable error."); + } } return Single.error(new IllegalArgumentException("Invalid scenario")); } @@ -321,9 +327,9 @@ private long calcPrimaryDelay(int tryNumber) { switch (this.factory.retryTestScenario) { case RETRY_TEST_SCENARIO_EXPONENTIAL_TIMING: return (long) Math.ceil( - ((pow(2L, tryNumber - 1) - 1L) * this.factory.options.getRetryDelayInMs()) / 1000); + ((pow(2L, tryNumber - 1) - 1L) * this.factory.options.retryDelayInMs()) / 1000); case RETRY_TEST_SCENARIO_FIXED_TIMING: - return (long) Math.ceil(this.factory.options.getRetryDelayInMs() / 1000); + return (long) Math.ceil(this.factory.options.retryDelayInMs() / 1000); default: throw new IllegalArgumentException("Invalid test scenario"); } @@ -357,8 +363,8 @@ private Single testDelayBounds(int primaryTryNumber, boolean tryin @Override protected void subscribeActual(SingleObserver observer) { try { - if (OffsetDateTime.now().isAfter(calcUpperBound(factory.time, primaryTryNumber, tryingPrimary)) || - OffsetDateTime.now() + if (OffsetDateTime.now().isAfter(calcUpperBound(factory.time, primaryTryNumber, tryingPrimary)) + || OffsetDateTime.now() .isBefore(calcLowerBound(factory.time, primaryTryNumber, tryingPrimary))) { throw new IllegalArgumentException("Delay was not within jitter bounds"); } @@ -382,10 +388,10 @@ private Single testMaxDelayBounds(Single response) { protected void subscribeActual(SingleObserver observer) { try { if (OffsetDateTime.now().isAfter(factory.time.plusSeconds( - (long) Math.ceil((factory.options.getMaxRetryDelayInMs() / 1000) + 1)))) { + (long) Math.ceil((factory.options.maxRetryDelayInMs() / 1000) + 1)))) { throw new IllegalArgumentException("Max retry delay exceeded"); } else if (OffsetDateTime.now().isBefore(factory.time.plusSeconds( - (long) Math.ceil((factory.options.getMaxRetryDelayInMs() / 1000) - 1)))) { + (long) Math.ceil((factory.options.maxRetryDelayInMs() / 1000) - 1)))) { throw new IllegalArgumentException("Retry did not delay long enough"); } diff --git a/src/test/java/com/microsoft/azure/storage/blob/RetryTest.groovy b/src/test/java/com/microsoft/azure/storage/blob/RetryTest.groovy index 998a0ce4b966..fa16ec1b7ff4 100644 --- a/src/test/java/com/microsoft/azure/storage/blob/RetryTest.groovy +++ b/src/test/java/com/microsoft/azure/storage/blob/RetryTest.groovy @@ -16,15 +16,14 @@ package com.microsoft.azure.storage.blob import com.microsoft.azure.storage.APISpec -import com.microsoft.azure.storage.blob.models.StorageErrorCode -import com.microsoft.azure.storage.blob.models.StorageErrorException import com.microsoft.rest.v2.http.HttpHeaders import com.microsoft.rest.v2.http.HttpMethod import com.microsoft.rest.v2.http.HttpPipeline import com.microsoft.rest.v2.http.HttpRequest import com.microsoft.rest.v2.http.HttpResponse +import com.microsoft.rest.v2.http.UnexpectedLengthException import io.reactivex.Flowable -import spock.lang.Specification + import spock.lang.Unroll // Tests for package-private functionality. @@ -63,7 +62,7 @@ class RetryTest extends APISpec { then: response.statusCode() == 503 - retryTestFactory.tryNumber == retryTestOptions.maxTries + retryTestFactory.tryNumber == retryTestOptions.maxTries() } def "Retries non retryable"() { @@ -112,7 +111,7 @@ class RetryTest extends APISpec { then: response.statusCode() == 200 - retryTestFactory.tryNumber == 5 + retryTestFactory.tryNumber == 3 } def "Retries try timeout"() { @@ -166,6 +165,23 @@ class RetryTest extends APISpec { retryTestFactory.tryNumber == 4 } + def "Retries non replyable flowable"() { + setup: + RequestRetryTestFactory retryTestFactory = new RequestRetryTestFactory( + RequestRetryTestFactory.RETRY_TEST_SCENARIO_NON_REPLAYABLE_FLOWABLE, retryTestOptions) + HttpPipeline pipeline = HttpPipeline.build(new RequestRetryFactory(retryTestOptions), retryTestFactory) + + when: + pipeline.sendRequestAsync(new HttpRequest(null, HttpMethod.GET, retryTestURL, + new HttpHeaders(), Flowable.just(RequestRetryTestFactory.RETRY_TEST_DEFAULT_DATA), + null)).blockingGet() + + then: + def e = thrown(IllegalStateException) + e.getMessage().startsWith("The request failed because") + e.getCause() instanceof UnexpectedLengthException + } + @Unroll def "Retries options invalid"() { when: diff --git a/swagger/generate.bat b/swagger/generate.bat index a4fd197ac712..0c538943072c 100644 --- a/swagger/generate.bat +++ b/swagger/generate.bat @@ -1,3 +1,3 @@ -set version=2.0.23 +set version=2.0.24 set url=https://github.com/Azure/autorest.java/releases/download/v%version%/microsoft.azure-autorest.java-%version%.tgz -autorest %~dp0README.md --use=%url% --reset --preview --implementation-subpackage=blob.implementation --models-subpackage=blob.models --generate-client-interfaces=false --required-parameter-client-methods=false --client-type-prefix=Generated \ No newline at end of file +autorest %~dp0README.md --use=%url% --reset --preview --implementation-subpackage=blob.implementation --models-subpackage=blob.models --generate-client-interfaces=false --required-parameter-client-methods=false --client-type-prefix=Generated --add-context-parameter=true \ No newline at end of file