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

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

/**
 * 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.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;

import javax.xml.stream.XMLStreamException;

import com.microsoft.azure.storage.*;
import com.microsoft.azure.storage.core.*;

/**
 * Represents a container in the Microsoft Azure Blob service.
 * 

* Containers hold directories, which are encapsulated as {@link CloudBlobDirectory} objects, and directories hold block * blobs and page blobs. Directories can also contain sub-directories. */ public final class CloudBlobContainer { /** * Converts the ACL string to a BlobContainerPermissions object. * * @param aclString * A String which specifies the ACLs to convert. * * @return A {@link BlobContainerPermissions} object which represents the ACLs. */ static BlobContainerPermissions getContainerAcl(final String aclString) { BlobContainerPublicAccessType accessType = BlobContainerPublicAccessType.parse(aclString); final BlobContainerPermissions retVal = new BlobContainerPermissions(); retVal.setPublicAccess(accessType); return retVal; } /** * Represents the container metadata. */ protected HashMap metadata = new HashMap(); /** * Holds the container properties. */ BlobContainerProperties properties = new BlobContainerProperties(); /** * Holds the name of the container. */ String name; /** * Holds the list of URIs for all locations. */ private StorageUri storageUri; /** * Holds a reference to the associated service client. */ private CloudBlobClient blobServiceClient; /** * Creates an instance of the CloudBlobContainer class using the specified URI. The blob URI should * include a SAS token unless anonymous access is to be used. * * @param uri * A java.net.URI object which represents the URI of the container. * * @throws StorageException * If a storage service error occurred. */ public CloudBlobContainer(final URI uri) throws StorageException { this(new StorageUri(uri)); } /** * Creates an instance of the CloudBlobContainer class using the specified URI. The blob URI should * include a SAS token unless anonymous access is to be used. * * @param storageUri * A {@link StorageUri} object which represents the URI of the container. * * @throws StorageException * If a storage service error occurred. */ public CloudBlobContainer(final StorageUri storageUri) throws StorageException { this(storageUri, (StorageCredentials) null); } /** * Creates an instance of the CloudBlobContainer class using the specified URI and credentials. * * @param uri * A java.net.URI object that represents the absolute URI of the container. * @param credentials * A {@link StorageCredentials} object used to authenticate access. * * @throws StorageException * If a storage service error occurred. */ public CloudBlobContainer(final URI uri, final StorageCredentials credentials) throws StorageException { this(new StorageUri(uri), credentials); } /** * Creates an instance of the CloudBlobContainer class using the specified StorageUri and credentials. * * @param storageUri * A {@link StorageUri} object which represents the absolute StorageUri of the container. * @param credentials * A {@link StorageCredentials} object used to authenticate access. * * @throws StorageException * If a storage service error occurred. */ public CloudBlobContainer(final StorageUri storageUri, final StorageCredentials credentials) throws StorageException { this.parseQueryAndVerify(storageUri, credentials); } /** * Creates an instance of the CloudBlobContainer class using the specified name and client. * * @param containerName * A String which represents the name of the container, which must adhere to container * naming rules. * The container name should not include any path separator characters (/). * Container names must be lowercase, between 3-63 characters long and must start with a letter or * number. Container names may contain only letters, numbers, and the dash (-) character. * @param client * A {@link CloudBlobClient} object that represents the associated service client, and that specifies the * endpoint for the Blob service. * * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI constructed based on the containerName is invalid. * * @see Naming and Referencing Containers, Blobs, * and Metadata */ protected CloudBlobContainer(final String containerName, final CloudBlobClient client) throws URISyntaxException, StorageException { Utility.assertNotNull("client", client); Utility.assertNotNull("containerName", containerName); this.storageUri = PathUtility.appendPathToUri(client.getStorageUri(), containerName); this.name = containerName; this.blobServiceClient = client; } /** * Creates the container. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void create() throws StorageException { this.create(BlobContainerPublicAccessType.OFF, null /* options */, null /* opContext */); } /** * Creates the container using the specified options and operation context. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void create(BlobRequestOptions options, OperationContext opContext) throws StorageException { this.create(BlobContainerPublicAccessType.OFF, options, opContext); } /** * Creates the container using the specified options and operation context. * * @param accessType * A {@link BlobContainerPublicAccessType} object that specifies whether data in the container may be * accessed publicly and what level of access is to be allowed. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void create(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (accessType == BlobContainerPublicAccessType.UNKNOWN) { throw new IllegalArgumentException(String.format(Utility.LOCALE_US, SR.ARGUMENT_OUT_OF_RANGE_ERROR, "accessType", accessType)); } if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); ExecutionEngine.executeWithRetry( this.blobServiceClient, this, createImpl(options, accessType), options.getRetryPolicyFactory(), opContext); } private StorageRequest createImpl( final BlobRequestOptions options, final BlobContainerPublicAccessType accessType) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { final HttpURLConnection request = BlobRequest.createContainer( container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessType); return request; } @Override public void setHeaders(HttpURLConnection connection, CloudBlobContainer container, OperationContext context) { BlobRequest.addMetadata(connection, container.metadata, context); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); } @Override public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_CREATED) { this.setNonExceptionedRetryableFailure(true); return null; } // Set attributes final BlobContainerAttributes attributes = BlobResponse.getBlobContainerAttributes( this.getConnection(), client.isUsePathStyleUris()); container.properties = attributes.getProperties(); container.name = attributes.getName(); if (accessType != null) { container.properties.setPublicAccess(accessType); } else { container.properties.setPublicAccess(BlobContainerPublicAccessType.OFF); } return null; } }; return putRequest; } /** * Creates the container if it does not exist. * * @return true if the container did not already exist and was created; otherwise, false. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public boolean createIfNotExists() throws StorageException { return this.createIfNotExists(BlobContainerPublicAccessType.OFF, null /* options */, null /* opContext */); } /** * Creates the container if it does not exist, using the specified request options and operation context. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. * Specifying null will use the default request options from the associated service client * ({@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return true if the container did not already exist and was created; otherwise, false. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public boolean createIfNotExists(BlobRequestOptions options, OperationContext opContext) throws StorageException { return this.createIfNotExists(BlobContainerPublicAccessType.OFF, options, opContext); } /** * Creates the container if it does not exist, using the specified request options and operation context. * * @param accessType * A {@link BlobContainerPublicAccessType} object that specifies whether data in the container may be * accessed publicly and what level of access is to be allowed. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. * Specifying null will use the default request options from the associated service client * ({@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return true if the container did not already exist and was created; otherwise, false. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public boolean createIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (accessType == BlobContainerPublicAccessType.UNKNOWN) { throw new IllegalArgumentException(String.format(Utility.LOCALE_US, SR.ARGUMENT_OUT_OF_RANGE_ERROR, "accessType", accessType)); } options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); boolean exists = this.exists(true /* primaryOnly */, null /* accessCondition */, options, opContext); if (exists) { return false; } else { try { this.create(accessType, options, opContext); return true; } catch (StorageException e) { if (e.getHttpStatusCode() == HttpURLConnection.HTTP_CONFLICT && StorageErrorCodeStrings.CONTAINER_ALREADY_EXISTS.equals(e.getErrorCode())) { return false; } else { throw e; } } } } /** * Deletes the container. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void delete() throws StorageException { this.delete(null /* accessCondition */, null /* options */, null /* opContext */); } /** * Deletes the container using the specified request options and operation context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void delete(AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); ExecutionEngine.executeWithRetry(this.blobServiceClient, this, deleteImpl(accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest deleteImpl( final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest(options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest( CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.deleteContainer( container.getTransformedAddress().getPrimaryUri(), options, context, accessCondition); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, -1L, context); } @Override public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_ACCEPTED) { this.setNonExceptionedRetryableFailure(true); } return null; } }; return putRequest; } /** * Deletes the container if it exists. * * @return true if the container did not already exist and was created; otherwise, false. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public boolean deleteIfExists() throws StorageException { return this.deleteIfExists(null /* accessCondition */, null /* options */, null /* opContext */); } /** * Deletes the container if it exists using the specified request options and operation context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return true if the container existed and was deleted; otherwise, false. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public boolean deleteIfExists(AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); boolean exists = this.exists(true /* primaryOnly */, accessCondition, options, opContext); if (exists) { try { this.delete(accessCondition, options, opContext); return true; } catch (StorageException e) { if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND && StorageErrorCodeStrings.CONTAINER_NOT_FOUND.equals(e.getErrorCode())) { return false; } else { throw e; } } } else { return false; } } /** * Downloads the container's attributes, which consist of metadata and properties. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void downloadAttributes() throws StorageException { this.downloadAttributes(null /* accessCondition */, null /* options */, null /* opContext */); } /** * Downloads the container's attributes, which consist of metadata and properties, using the specified request * options and operation context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void downloadAttributes(AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.downloadAttributesImpl(accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest downloadAttributesImpl( final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @Override public void setRequestLocationMode() { this.setRequestLocationMode(RequestLocationMode.PRIMARY_OR_SECONDARY); } @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.getContainerProperties( container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, -1L, context); } @Override public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); return null; } // Set attributes final BlobContainerAttributes attributes = BlobResponse.getBlobContainerAttributes( this.getConnection(), client.isUsePathStyleUris()); container.metadata = attributes.getMetadata(); container.properties = attributes.getProperties(); container.name = attributes.getName(); return null; } }; return getRequest; } /** * Downloads the permission settings for the container. * * @return A {@link BlobContainerPermissions} object that represents the container's permissions. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public BlobContainerPermissions downloadPermissions() throws StorageException { return this.downloadPermissions(null /* accessCondition */, null /* options */, null /* opContext */); } /** * Downloads the permissions settings for the container using the specified request options and operation context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return A {@link BlobContainerPermissions} object that represents the container's permissions. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public BlobContainerPermissions downloadPermissions(AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, downloadPermissionsImpl(accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest downloadPermissionsImpl( final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @Override public void setRequestLocationMode() { this.setRequestLocationMode(RequestLocationMode.PRIMARY_OR_SECONDARY); } @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.getAcl(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, accessCondition, context); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, -1L, context); } @Override public BlobContainerPermissions preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); } container.updatePropertiesFromResponse(this.getConnection()); final String aclString = BlobResponse.getAcl(this.getConnection()); final BlobContainerPermissions containerAcl = getContainerAcl(aclString); container.properties.setPublicAccess(containerAcl.getPublicAccess()); return containerAcl; } @Override public BlobContainerPermissions postProcessResponse(HttpURLConnection connection, CloudBlobContainer container, CloudBlobClient client, OperationContext context, BlobContainerPermissions containerAcl) throws Exception { HashMap accessIds = SharedAccessPolicyHandler.getAccessIdentifiers(this .getConnection().getInputStream(), SharedAccessBlobPolicy.class); for (final String key : accessIds.keySet()) { containerAcl.getSharedAccessPolicies().put(key, accessIds.get(key)); } return containerAcl; } }; return getRequest; } /** * Returns a value that indicates whether the container exists. * * @return true if the container exists, otherwise false. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public boolean exists() throws StorageException { return this.exists(null /* accessCondition */, null /* options */, null /* opContext */); } /** * Returns a value that indicates whether the container exists, using the specified request options and operation * context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return true if the container exists, otherwise false. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public boolean exists(final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { return this.exists(false, accessCondition, options, opContext); } @DoesServiceRequest private boolean exists(final boolean primaryOnly, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.existsImpl(primaryOnly, accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest existsImpl(final boolean primaryOnly, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @Override public void setRequestLocationMode() { this.setRequestLocationMode(primaryOnly ? RequestLocationMode.PRIMARY_ONLY : RequestLocationMode.PRIMARY_OR_SECONDARY); } @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.getContainerProperties( container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, -1L, context); } @Override public Boolean preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_OK) { // Set attributes final BlobContainerAttributes attributes = BlobResponse.getBlobContainerAttributes( this.getConnection(), client.isUsePathStyleUris()); container.metadata = attributes.getMetadata(); container.properties = attributes.getProperties(); container.name = attributes.getName(); return Boolean.valueOf(true); } else if (this.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) { return Boolean.valueOf(false); } else { this.setNonExceptionedRetryableFailure(true); // return false instead of null to avoid SCA issues return false; } } }; return getRequest; } /** * Returns a shared access signature for the container. Note this does not contain the leading "?". * * @param policy * An {@link SharedAccessBlobPolicy} object that represents the access policy for the shared access * signature. * @param groupPolicyIdentifier * A String which represents the container-level access policy. * * @return A String which represents a shared access signature for the container. * * @throws StorageException * If a storage service error occurred. * @throws InvalidKeyException * If the key is invalid. */ public String generateSharedAccessSignature(final SharedAccessBlobPolicy policy, final String groupPolicyIdentifier) throws InvalidKeyException, StorageException { return this.generateSharedAccessSignature( policy, groupPolicyIdentifier, null /* IP range */, null /* protocols */); } /** * Returns a shared access signature for the container. Note this does not contain the leading "?". * * @param policy * An {@link SharedAccessBlobPolicy} object that represents the access policy for the shared access * signature. * @param groupPolicyIdentifier * A String which represents the container-level access policy. * @param ipRange * A {@link IPRange} object containing the range of allowed IP addresses. * @param protocols * A {@link SharedAccessProtocols} representing the allowed Internet protocols. * * @return A String which represents a shared access signature for the container. * * @throws StorageException * If a storage service error occurred. * @throws InvalidKeyException * If the key is invalid. */ public String generateSharedAccessSignature(final SharedAccessBlobPolicy policy, final String groupPolicyIdentifier, final IPRange ipRange, final SharedAccessProtocols protocols) throws InvalidKeyException, StorageException { if (!StorageCredentialsHelper.canCredentialsSignRequest(this.blobServiceClient.getCredentials())) { final String errorMessage = SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY; throw new IllegalArgumentException(errorMessage); } final String resourceName = this.getSharedAccessCanonicalName(); final String signature = SharedAccessSignatureHelper.generateSharedAccessSignatureHashForBlobAndFile( policy, null /* SharedAccessBlobHeaders */, groupPolicyIdentifier, resourceName, ipRange, protocols, this.blobServiceClient); final UriQueryBuilder builder = SharedAccessSignatureHelper.generateSharedAccessSignatureForBlobAndFile(policy, null /* SharedAccessBlobHeaders */, groupPolicyIdentifier, "c", ipRange, protocols, signature); return builder.toString(); } /** * Returns a reference to a {@link CloudAppendBlob} object that represents an append blob in this container. * * @param blobName * A String that represents the name of the blob. * * @return A {@link CloudAppendBlob} object that represents a reference to the specified append blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ public CloudAppendBlob getAppendBlobReference(final String blobName) throws URISyntaxException, StorageException { return this.getAppendBlobReference(blobName, null); } /** * Returns a reference to a {@link CloudAppendBlob} object that represents an append blob in the container, using the * specified snapshot ID. * * @param blobName * A String that represents the name of the blob. * @param snapshotID * A String that represents the snapshot ID of the blob. * * @return A {@link CloudAppendBlob} object that represents a reference to the specified append blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ public CloudAppendBlob getAppendBlobReference(final String blobName, final String snapshotID) throws URISyntaxException, StorageException { return new CloudAppendBlob(blobName, snapshotID, this); } /** * Returns a reference to a {@link CloudBlockBlob} object that represents a block blob in this container. * * @param blobName * A String that represents the name of the blob. * * @return A {@link CloudBlockBlob} object that represents a reference to the specified block blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ public CloudBlockBlob getBlockBlobReference(final String blobName) throws URISyntaxException, StorageException { return this.getBlockBlobReference(blobName, null); } /** * Returns a reference to a {@link CloudBlockBlob} object that represents a block blob in this container, using the * specified snapshot ID. * * @param blobName * A String that represents the name of the blob. * @param snapshotID * A String that represents the snapshot ID of the blob. * * @return A {@link CloudBlockBlob} object that represents a reference to the specified block blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ public CloudBlockBlob getBlockBlobReference(final String blobName, final String snapshotID) throws URISyntaxException, StorageException { return new CloudBlockBlob(blobName, snapshotID, this); } /** * Returns a reference to a {@link CloudBlobDirectory} object that represents a virtual blob directory within this * container. * * @param directoryName * A String that represents the name of the virtual blob directory. If the root directory * (the directory representing the container itself) is desired, use an empty string. * @return A {@link CloudBlobDirectory} that represents a virtual blob directory within this container. * @throws URISyntaxException * If the resource URI is invalid. */ public CloudBlobDirectory getDirectoryReference(String directoryName) throws URISyntaxException { Utility.assertNotNull("directoryName", directoryName); // if the directory name does not end in the delimiter, add the delimiter if (!directoryName.isEmpty() && !directoryName.endsWith(this.blobServiceClient.getDirectoryDelimiter())) { directoryName = directoryName.concat(this.blobServiceClient.getDirectoryDelimiter()); } final StorageUri address = PathUtility.appendPathToUri(this.storageUri, directoryName); return new CloudBlobDirectory(address, directoryName, this.blobServiceClient, this); } /** * Gets a reference to a blob in this container. The blob must already exist on the service. * * Unlike the other get*Reference methods, this method does a service request to retrieve the blob's metadata and * properties. The returned blob may be used directly as a CloudBlob or cast using either instanceof or * getProperties().getBlobType() to determine its subtype. * * @param blobName * A String that represents the name of the blob. * * @return A {@link CloudBlob} object that represents a reference to the specified blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ @DoesServiceRequest public final CloudBlob getBlobReferenceFromServer(final String blobName) throws URISyntaxException, StorageException { return this.getBlobReferenceFromServer(blobName, null, null, null, null); } /** * Gets a reference to a blob in this container. The blob must already exist on the service. * * Unlike the other get*Reference methods, this method does a service request to retrieve the blob's metadata and * properties. The returned blob may be used directly as a CloudBlob or cast using either instanceof or * getProperties().getBlobType() to determine its subtype. * * @param blobName * A String that represents the name of the blob. * @param snapshotID * A String that represents the snapshot ID of the blob. * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return A {@link CloudBlob} object that represents a reference to the specified blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ @DoesServiceRequest public final CloudBlob getBlobReferenceFromServer(final String blobName, final String snapshotID, AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws URISyntaxException, StorageException { if (opContext == null) { opContext = new OperationContext(); } options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); StorageUri blobUri = PathUtility.appendPathToUri(this.getStorageUri(), blobName); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.getBlobReferenceFromServerImpl(blobName, blobUri, snapshotID, accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest getBlobReferenceFromServerImpl( final String blobName, final StorageUri blobUri, final String snapshotID, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest getRequest = new StorageRequest( options, this.getStorageUri()) { @Override public void setRequestLocationMode() { this.setRequestLocationMode(RequestLocationMode.PRIMARY_OR_SECONDARY); } @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { StorageUri transformedblobUri = CloudBlobContainer.this.getServiceClient().getCredentials().transformUri(blobUri, context); return BlobRequest.getBlobProperties(transformedblobUri.getUri(this.getCurrentLocation()), options, context, accessCondition, snapshotID); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, -1L, context); } @Override public CloudBlob preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); return null; } // Set attributes final BlobAttributes retrievedAttributes = BlobResponse.getBlobAttributes(this.getConnection(), blobUri, snapshotID); CloudBlob blob; switch (retrievedAttributes.getProperties().getBlobType()) { case APPEND_BLOB: blob = container.getAppendBlobReference(blobName, snapshotID); break; case BLOCK_BLOB: blob = container.getBlockBlobReference(blobName, snapshotID); break; case PAGE_BLOB: blob = container.getPageBlobReference(blobName, snapshotID); break; default: throw new StorageException(StorageErrorCodeStrings.INCORRECT_BLOB_TYPE, SR.INVALID_RESPONSE_RECEIVED, Constants.HeaderConstants.HTTP_UNUSED_306, null, null); } blob.properties = retrievedAttributes.getProperties(); blob.metadata = retrievedAttributes.getMetadata(); return blob; } }; return getRequest; } /** * Returns the metadata for the container. This value is initialized with the metadata from the queue by a call to * {@link #downloadAttributes}, and is set on the queue with a call to {@link #uploadMetadata}. * * @return A java.util.HashMap object that represents the metadata for the container. */ public HashMap getMetadata() { return this.metadata; } /** * Returns the name of the container. * * @return A String that represents the name of the container. */ public String getName() { return this.name; } /** * Returns the list of URIs for all locations. * * @return A {@link StorageUri} object which represents the list of URIs for all locations.. */ public StorageUri getStorageUri() { return this.storageUri; } /** * Returns a reference to a {@link CloudPageBlob} object that represents a page blob in this container. * * @param blobName * A String that represents the name of the blob. * * @return A {@link CloudPageBlob} object that represents a reference to the specified page blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ public CloudPageBlob getPageBlobReference(final String blobName) throws URISyntaxException, StorageException { return this.getPageBlobReference(blobName, null); } /** * Returns a reference to a {@link CloudPageBlob} object that represents a page blob in the container, using the * specified snapshot ID. * * @param blobName * A String that represents the name of the blob. * @param snapshotID * A String that represents the snapshot ID of the blob. * * @return A {@link CloudPageBlob} object that represents a reference to the specified page blob. * * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ public CloudPageBlob getPageBlobReference(final String blobName, final String snapshotID) throws URISyntaxException, StorageException { return new CloudPageBlob(blobName, snapshotID, this); } /** * Returns the properties for the container. * * @return A {@link BlobContainerProperties} object that represents the properties for the container. */ public BlobContainerProperties getProperties() { return this.properties; } /** * Returns the Blob service client associated with this container. * * @return A {@link CloudBlobClient} object that represents the service client associated with this container. */ public CloudBlobClient getServiceClient() { return this.blobServiceClient; } /** * Returns the canonical name for shared access. * * @return the canonical name for shared access. */ private String getSharedAccessCanonicalName() { String accountName = this.getServiceClient().getCredentials().getAccountName(); String containerName = this.getName(); return String.format("/%s/%s/%s", SR.BLOB, accountName, containerName); } /** * Returns the URI after applying the authentication transformation. * * @return A java.net.URI object that represents the URI after applying the authentication * transformation. * * @throws IllegalArgumentException * If an unexpected value is passed. * @throws StorageException * If a storage service error occurred. * @throws URISyntaxException * If the resource URI is invalid. */ private StorageUri getTransformedAddress() throws URISyntaxException, StorageException { return this.blobServiceClient.getCredentials().transformUri(this.storageUri); } /** * Returns the URI for this container. * * @return The absolute URI to the container. */ public URI getUri() { return this.storageUri.getPrimaryUri(); } /** * Returns an enumerable collection of blob items for the container. * * @return An enumerable collection of {@link ListBlobItem} objects retrieved lazily that represents the items in * this container. */ @DoesServiceRequest public Iterable listBlobs() { return this.listBlobs(null, false, EnumSet.noneOf(BlobListingDetails.class), null, null); } /** * Returns an enumerable collection of blob items for the container whose names begin with the specified prefix. * * @param prefix * A String that represents the blob name prefix. This value must be preceded either by the * name of the container or by the absolute path to the container. * * @return An enumerable collection of {@link ListBlobItem} objects retrieved lazily that represents the * items whose names begin with the specified prefix in this container. */ @DoesServiceRequest public Iterable listBlobs(final String prefix) { return this.listBlobs(prefix, false); } /** * Returns an enumerable collection of blob items for the container whose names begin with the specified prefix * using the specified flat or hierarchical option. * * @param prefix * A String that represents the blob name prefix. This value must be preceded either by the * name of the container or by the absolute path to the container. * @param useFlatBlobListing * true to indicate that the returned list will be flat; false to indicate that * the returned list will be hierarchical. * @return An enumerable collection of {@link ListBlobItem} objects retrieved lazily that represents the * items whose names begin with the specified prefix in this container. */ @DoesServiceRequest public Iterable listBlobs(final String prefix, final boolean useFlatBlobListing) { return this.listBlobs(prefix, useFlatBlobListing, EnumSet.noneOf(BlobListingDetails.class), null, null); } /** * Returns an enumerable collection of blob items for the container whose names begin with the specified prefix, * using the specified flat or hierarchical option, listing details options, request options, and operation context. * * @param prefix * A String that represents the blob name prefix. This value must be preceded either by the * name of the container or by the absolute path to the container. * @param useFlatBlobListing * true to indicate that the returned list will be flat; false to indicate that * the returned list will be hierarchical. * @param listingDetails * A java.util.EnumSet object that contains {@link BlobListingDetails} values that indicate * whether snapshots, soft-deleted blobs, metadata, and/or uncommitted blocks are returned. Committed blocks are always * returned. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * @return An enumerable collection of {@link ListBlobItem} objects retrieved lazily that represents the * items whose names begin with the specified prefix in this container. */ @DoesServiceRequest public Iterable listBlobs(final String prefix, final boolean useFlatBlobListing, final EnumSet listingDetails, BlobRequestOptions options, OperationContext opContext) { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); if (!useFlatBlobListing && listingDetails != null && listingDetails.contains(BlobListingDetails.SNAPSHOTS)) { throw new IllegalArgumentException(SR.SNAPSHOT_LISTING_ERROR); } SegmentedStorageRequest segmentedRequest = new SegmentedStorageRequest(); return new LazySegmentedIterable( this.listBlobsSegmentedImpl(prefix, useFlatBlobListing, listingDetails, null, options, segmentedRequest), this.blobServiceClient, this, options.getRetryPolicyFactory(), opContext); } /** * Returns a result segment of an enumerable collection of blob items in the container. * * @return A {@link ResultSegment} object that contains a segment of the enumerable collection of * {@link ListBlobItem} objects that represent the blob items in the container. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public ResultSegment listBlobsSegmented() throws StorageException { return this.listBlobsSegmented(null, false, EnumSet.noneOf(BlobListingDetails.class), null, null, null, null); } /** * Returns a result segment containing a collection of blob items whose names begin with the specified prefix. * * @param prefix * A String that represents the prefix of the blob name. * * @return A {@link ResultSegment} object that contains a segment of the enumerable collection of * {@link ListBlobItem} objects that represent the blob items whose names begin with the specified prefix in * the container. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public ResultSegment listBlobsSegmented(final String prefix) throws StorageException { return this.listBlobsSegmented(prefix, false, EnumSet.noneOf(BlobListingDetails.class), null, null, null, null); } /** * Returns a result segment containing a collection of blob items whose names begin with the * specified prefix, using the specified flat or hierarchical option, listing details options, * request options, and operation context. * * @param prefix * A String that represents the prefix of the blob name. * @param useFlatBlobListing * true to indicate that the returned list will be flat; * false to indicate that the returned list will be hierarchical. * @param listingDetails * A java.util.EnumSet object that contains {@link BlobListingDetails} * values that indicate whether snapshots, soft-deleted blobs, metadata, and/or uncommitted blocks * are returned. Committed blocks are always returned. * @param maxResults * The maximum number of results to retrieve. If null or greater * than 5000, the server will return up to 5,000 items. Must be at least 1. * @param continuationToken * A {@link ResultContinuation} object that represents a continuation token returned * by a previous listing operation. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the * request. Specifying null will use the default request options from * the associated service client ({@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current * operation. This object is used to track requests to the storage service, * and to provide additional runtime information about the operation. * * @return A {@link ResultSegment} object that contains a segment of the enumerable collection * of {@link ListBlobItem} objects that represent the block items whose names begin * with the specified prefix in the container. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public ResultSegment listBlobsSegmented(final String prefix, final boolean useFlatBlobListing, final EnumSet listingDetails, final Integer maxResults, final ResultContinuation continuationToken, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); Utility.assertContinuationType(continuationToken, ResultContinuationType.BLOB); if (!useFlatBlobListing && listingDetails != null && listingDetails.contains(BlobListingDetails.SNAPSHOTS)) { throw new IllegalArgumentException(SR.SNAPSHOT_LISTING_ERROR); } SegmentedStorageRequest segmentedRequest = new SegmentedStorageRequest(); segmentedRequest.setToken(continuationToken); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.listBlobsSegmentedImpl(prefix, useFlatBlobListing, listingDetails, maxResults, options, segmentedRequest), options .getRetryPolicyFactory(), opContext); } private StorageRequest> listBlobsSegmentedImpl( final String prefix, final boolean useFlatBlobListing, final EnumSet listingDetails, final Integer maxResults, final BlobRequestOptions options, final SegmentedStorageRequest segmentedRequest) { Utility.assertContinuationType(segmentedRequest.getToken(), ResultContinuationType.BLOB); Utility.assertNotNull("options", options); final String delimiter = useFlatBlobListing ? null : this.blobServiceClient.getDirectoryDelimiter(); final BlobListingContext listingContext = new BlobListingContext(prefix, maxResults, delimiter, listingDetails); final StorageRequest> getRequest = new StorageRequest>( options, this.getStorageUri()) { @Override public void setRequestLocationMode() { this.setRequestLocationMode(Utility.getListingLocationMode(segmentedRequest.getToken())); } @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { listingContext.setMarker(segmentedRequest.getToken() != null ? segmentedRequest.getToken() .getNextMarker() : null); return BlobRequest.listBlobs(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, listingContext); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, -1L, context); } @Override public ResultSegment preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); } return null; } @Override public ResultSegment postProcessResponse(HttpURLConnection connection, CloudBlobContainer container, CloudBlobClient client, OperationContext context, ResultSegment storageObject) throws Exception { final ListBlobsResponse response = BlobListHandler.getBlobList(connection.getInputStream(), container); ResultContinuation newToken = null; if (response.getNextMarker() != null) { newToken = new ResultContinuation(); newToken.setNextMarker(response.getNextMarker()); newToken.setContinuationType(ResultContinuationType.BLOB); newToken.setTargetLocation(this.getResult().getTargetLocation()); } final ResultSegment resSegment = new ResultSegment(response.getResults(), response.getMaxResults(), newToken); // Important for listBlobs because this is required by the lazy iterator between executions. segmentedRequest.setToken(resSegment.getContinuationToken()); return resSegment; } }; return getRequest; } /** * Returns an enumerable collection of containers for the service client associated with this container. * * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represent the * containers for the service client associated with this container. */ @DoesServiceRequest public Iterable listContainers() { return this.blobServiceClient.listContainers(); } /** * Returns an enumerable collection of containers whose names begin with the specified prefix for the service client * associated with this container. * * @param prefix * A String that represents the container name prefix. * * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represent the * containers whose names begin with the specified prefix for the service client associated with this * container. */ @DoesServiceRequest public Iterable listContainers(final String prefix) { return this.blobServiceClient.listContainers(prefix); } /** * Returns an enumerable collection of containers whose names begin with the specified prefix for the service client * associated with this container, using the specified details setting, request options, and operation context. * * @param prefix * A String that represents the container name prefix. * @param detailsIncluded * A {@link ContainerListingDetails} value that indicates whether container metadata will be returned. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return An enumerable collection of {@link CloudBlobContainer} objects retrieved lazily that represents the * containers for the * service client associated with this container. */ @DoesServiceRequest public Iterable listContainers(final String prefix, final ContainerListingDetails detailsIncluded, final BlobRequestOptions options, final OperationContext opContext) { return this.blobServiceClient.listContainers(prefix, detailsIncluded, options, opContext); } /** * Returns a result segment of an enumerable collection of containers for the service client associated with this * container. * * @return A {@link ResultSegment} object that contains a segment of the enumerable collection of * {@link CloudBlobContainer} objects that represent the containers for the service client associated with * this container. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public ResultSegment listContainersSegmented() throws StorageException { return this.blobServiceClient.listContainersSegmented(); } /** * Returns a result segment of an enumerable collection of containers whose names begin with the specified prefix * for the service client associated with this container. * * @param prefix * A String that represents the blob name prefix. * * @return A {@link ResultSegment} object that contains a segment of the enumerable collection of * {@link CloudBlobContainer} objects that represent the containers whose names begin with the specified * prefix for the service client associated with this container. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public ResultSegment listContainersSegmented(final String prefix) throws StorageException { return this.blobServiceClient.listContainersSegmented(prefix); } /** * Returns a result segment containing a collection of containers whose names begin with * the specified prefix for the service client associated with this container, * using the specified listing details options, request options, and operation context. * * @param prefix * A String that represents the prefix of the container name. * @param detailsIncluded * A {@link ContainerListingDetails} object that indicates whether metadata is included. * @param maxResults * The maximum number of results to retrieve. If null or greater * than 5000, the server will return up to 5,000 items. Must be at least 1. * @param continuationToken * A {@link ResultContinuation} object that represents a continuation token * returned by a previous listing operation. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the * request. Specifying null will use the default request options from * the associated service client ( {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current * operation. This object is used to track requests to the storage service, * and to provide additional runtime information about the operation. * * @return A {@link ResultSegment} object that contains a segment of the enumerable collection * of {@link CloudBlobContainer} objects that represent the containers whose names * begin with the specified prefix for the service client associated with this container. * * @throws StorageException * If a storage service error occurred. * */ @DoesServiceRequest public ResultSegment listContainersSegmented(final String prefix, final ContainerListingDetails detailsIncluded, final Integer maxResults, final ResultContinuation continuationToken, final BlobRequestOptions options, final OperationContext opContext) throws StorageException { return this.blobServiceClient.listContainersSegmented(prefix, detailsIncluded, maxResults, continuationToken, options, opContext); } /** * Verifies the passed in URI. Then parses it and uses its components to populate this resource's properties. * * @param completeUri * A {@link StorageUri} object which represents the complete URI. * @param credentials * A {@link StorageCredentials} object used to authenticate access. * @throws StorageException * If a storage service error occurred. */ private void parseQueryAndVerify(final StorageUri completeUri, final StorageCredentials credentials) throws StorageException { Utility.assertNotNull("completeUri", completeUri); if (!completeUri.isAbsolute()) { throw new IllegalArgumentException(String.format(SR.RELATIVE_ADDRESS_NOT_PERMITTED, completeUri.toString())); } this.storageUri = PathUtility.stripURIQueryAndFragment(completeUri); final StorageCredentialsSharedAccessSignature parsedCredentials = SharedAccessSignatureHelper.parseQuery(completeUri); if (credentials != null && parsedCredentials != null) { throw new IllegalArgumentException(SR.MULTIPLE_CREDENTIALS_PROVIDED); } try { final boolean usePathStyleUris = Utility.determinePathStyleFromUri(this.storageUri.getPrimaryUri()); this.blobServiceClient = new CloudBlobClient(PathUtility.getServiceClientBaseAddress( this.getStorageUri(), usePathStyleUris), credentials != null ? credentials : parsedCredentials); this.name = PathUtility.getContainerNameFromUri(this.storageUri.getPrimaryUri(), usePathStyleUris); } catch (final URISyntaxException e) { throw Utility.generateNewUnexpectedStorageException(e); } } void updatePropertiesFromResponse(HttpURLConnection request) { // ETag this.getProperties().setEtag(request.getHeaderField(Constants.HeaderConstants.ETAG)); // Last Modified if (0 != request.getLastModified()) { final Calendar lastModifiedCalendar = Calendar.getInstance(Utility.LOCALE_US); lastModifiedCalendar.setTimeZone(Utility.UTC_ZONE); lastModifiedCalendar.setTime(new Date(request.getLastModified())); this.getProperties().setLastModified(lastModifiedCalendar.getTime()); } } /** * Sets the metadata collection of name-value pairs to be set on the container with an {@link #uploadMetadata} call. * This collection will overwrite any existing container metadata. If this is set to an empty collection, the * container metadata will be cleared on an {@link #uploadMetadata} call. * * @param metadata * A java.util.HashMap object that represents the metadata being assigned to the container. */ public void setMetadata(final HashMap metadata) { this.metadata = metadata; } /** * Sets the list of URIs for all locations. * * @param storageUri * A {@link StorageUri} object which represents the list of URIs for all locations. */ protected void setStorageUri(final StorageUri storageUri) { this.storageUri = storageUri; } /** * Sets the properties for the container. * * @param properties * A {@link BlobContainerProperties} object that represents the properties being assigned to the * container. */ protected void setProperties(final BlobContainerProperties properties) { this.properties = properties; } /** * Uploads the container's metadata. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void uploadMetadata() throws StorageException { this.uploadMetadata(null /* accessCondition */, null /* options */, null /* opContext */); } /** * Uploads the container's metadata using the specified request options and operation context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void uploadMetadata(AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.uploadMetadataImpl(accessCondition, options), options.getRetryPolicyFactory(), opContext); } @DoesServiceRequest private StorageRequest uploadMetadataImpl( final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.setContainerMetadata( container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition); } @Override public void setHeaders(HttpURLConnection connection, CloudBlobContainer container, OperationContext context) { BlobRequest.addMetadata(connection, container.metadata, context); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); } @Override public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); } container.updatePropertiesFromResponse(this.getConnection()); return null; } }; return putRequest; } /** * Uploads the container's permissions. * * @param permissions * A {@link BlobContainerPermissions} object that represents the permissions to upload. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void uploadPermissions(final BlobContainerPermissions permissions) throws StorageException { this.uploadPermissions(permissions, null /* accessCondition */, null /* options */, null /* opContext */); } /** * Uploads the container's permissions using the specified request options and operation context. * * @param permissions * A {@link BlobContainerPermissions} object that represents the permissions to upload. * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public void uploadPermissions(final BlobContainerPermissions permissions, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (permissions.getPublicAccess() == BlobContainerPublicAccessType.UNKNOWN) { throw new IllegalArgumentException(String.format(Utility.LOCALE_US, SR.ARGUMENT_OUT_OF_RANGE_ERROR, "accessType", permissions.getPublicAccess())); } if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); ExecutionEngine.executeWithRetry(this.blobServiceClient, this, uploadPermissionsImpl(permissions, accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest uploadPermissionsImpl( final BlobContainerPermissions permissions, final AccessCondition accessCondition, final BlobRequestOptions options) throws StorageException { try { final StringWriter outBuffer = new StringWriter(); SharedAccessPolicySerializer.writeSharedAccessIdentifiersToStream(permissions.getSharedAccessPolicies(), outBuffer); final byte[] aclBytes = outBuffer.toString().getBytes(Constants.UTF8_CHARSET); final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { this.setSendStream(new ByteArrayInputStream(aclBytes)); this.setLength((long) aclBytes.length); return BlobRequest.setAcl(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition, permissions.getPublicAccess()); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, aclBytes.length, context); } @Override public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); return null; } container.updatePropertiesFromResponse(this.getConnection()); container.getProperties().setPublicAccess(permissions.getPublicAccess()); return null; } }; return putRequest; } catch (final IllegalArgumentException e) { StorageException translatedException = StorageException.translateClientException(e); throw translatedException; } catch (final XMLStreamException e) { // The request was not even made. There was an error while trying to read the permissions. Just throw. StorageException translatedException = StorageException.translateClientException(e); throw translatedException; } catch (UnsupportedEncodingException e) { // The request was not even made. There was an error while trying to read the permissions. Just throw. StorageException translatedException = StorageException.translateClientException(e); throw translatedException; } } /** * Acquires a new infinite lease on the container. * * @return A String that represents the lease ID. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final String acquireLease() throws StorageException { return this.acquireLease(null /* leaseTimeInSeconds */, null /* proposedLeaseId */); } /** * Acquires a new lease on the container with the specified lease time and proposed lease ID. * * @param leaseTimeInSeconds * An Integer which specifies the span of time for which to acquire the lease, in seconds. * If null, an infinite lease will be acquired. If not null, the value must be greater than * zero. * * @param proposedLeaseId * A String that represents the proposed lease ID for the new lease, * or null if no lease ID is proposed. * * @return A String that represents the lease ID. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final String acquireLease(final Integer leaseTimeInSeconds, final String proposedLeaseId) throws StorageException { return this.acquireLease(leaseTimeInSeconds, proposedLeaseId, null /* accessCondition */, null /* options */, null /* opContext */); } /** * Acquires a new lease on the container with the specified lease time, proposed lease ID, request * options, and operation context. * * @param leaseTimeInSeconds * An Integer which specifies the span of time for which to acquire the lease, in seconds. * If null, an infinite lease will be acquired. If not null, the value must be greater than * zero. * * @param proposedLeaseId * A String that represents the proposed lease ID for the new lease, * or null if no lease ID is proposed. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client * ({@link CloudBlobClient}). * * @param opContext * An {@link OperationContext} object that represents the context for the current operation. The context * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return A String that represents the lease ID. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final String acquireLease(final Integer leaseTimeInSeconds, final String proposedLeaseId, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.acquireLeaseImpl(leaseTimeInSeconds, proposedLeaseId, accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest acquireLeaseImpl( final Integer leaseTimeInSeconds, final String proposedLeaseId, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.leaseContainer(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition, LeaseAction.ACQUIRE, leaseTimeInSeconds, proposedLeaseId, null /* breakPeriodInSeconds */); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); } @Override public String preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_CREATED) { this.setNonExceptionedRetryableFailure(true); return null; } container.updatePropertiesFromResponse(this.getConnection()); return BlobResponse.getLeaseID(this.getConnection()); } }; return putRequest; } /** * Renews an existing lease with the specified access conditions. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the container. The lease * ID is required to be set with an access condition. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final void renewLease(final AccessCondition accessCondition) throws StorageException { this.renewLease(accessCondition, null /* options */, null /* opContext */); } /** * Renews an existing lease with the specified access conditions, request options, and operation context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. The lease ID is * required to be set with an access condition. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client * ({@link CloudBlobClient}). * * @param opContext * An {@link OperationContext} object that represents the context for the current operation. The context * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final void renewLease(final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { Utility.assertNotNull("accessCondition", accessCondition); Utility.assertNotNullOrEmpty("leaseID", accessCondition.getLeaseID()); if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.renewLeaseImpl(accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest renewLeaseImpl( final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.leaseContainer(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition, LeaseAction.RENEW, null /* leaseTimeInSeconds */, null /* proposedLeaseId */, null /* breakPeriodInseconds */); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); } @Override public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); return null; } container.updatePropertiesFromResponse(this.getConnection()); return null; } }; return putRequest; } /** * Releases the lease on the container. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. The lease ID is * required to be set with an access condition. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final void releaseLease(final AccessCondition accessCondition) throws StorageException { this.releaseLease(accessCondition, null /* options */, null /* opContext */); } /** * Releases the lease on the container using the specified access conditions, request options, and operation * context. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. The lease ID is * required to be set with an access condition. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client * ({@link CloudBlobClient}). * * @param opContext * An {@link OperationContext} object that represents the context for the current operation. The context * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final void releaseLease(final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { Utility.assertNotNull("accessCondition", accessCondition); Utility.assertNotNullOrEmpty("leaseID", accessCondition.getLeaseID()); if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.releaseLeaseImpl(accessCondition, options), options.getRetryPolicyFactory(), opContext); } private StorageRequest releaseLeaseImpl( final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.leaseContainer(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition, LeaseAction.RELEASE, null, null, null); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); } @Override public Void preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); return null; } container.updatePropertiesFromResponse(this.getConnection()); return null; } }; return putRequest; } /** * Breaks the lease and ensures that another client cannot acquire a new lease until the current lease * period has expired. * * @param breakPeriodInSeconds * An Integer which specifies the time to wait, in seconds, until the current lease is * broken. * If null, the break period is the remainder of the current lease, or zero for infinite leases. * * @return The time, in seconds, remaining in the lease period. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final long breakLease(final Integer breakPeriodInSeconds) throws StorageException { return this.breakLease(breakPeriodInSeconds, null /* accessCondition */, null, null); } /** * Breaks the existing lease, using the specified request options and operation context, and ensures that * another client cannot acquire a new lease until the current lease period has expired. * * @param breakPeriodInSeconds * An Integer which specifies the time to wait, in seconds, until the current lease is * broken. * If null, the break period is the remainder of the current lease, or zero for infinite leases. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client * ({@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. The context * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return The time, in seconds, remaining in the lease period. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final long breakLease(final Integer breakPeriodInSeconds, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } if (breakPeriodInSeconds != null) { Utility.assertGreaterThanOrEqual("breakPeriodInSeconds", breakPeriodInSeconds, 0); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.breakLeaseImpl(breakPeriodInSeconds, accessCondition, options), options.getRetryPolicyFactory(), opContext); } private final StorageRequest breakLeaseImpl( final Integer breakPeriodInSeconds, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putCmd = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.leaseContainer(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition, LeaseAction.BREAK, null, null, breakPeriodInSeconds); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); } @Override public Long preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_ACCEPTED) { this.setNonExceptionedRetryableFailure(true); return -1L; } container.updatePropertiesFromResponse(this.getConnection()); final String leaseTime = BlobResponse.getLeaseTime(this.getConnection()); return Utility.isNullOrEmpty(leaseTime) ? -1L : Long.parseLong(leaseTime); } }; return putCmd; } /** * Changes the existing lease ID to the proposed lease ID. * * @param proposedLeaseId * A String that represents the proposed lease ID for the new lease, * or null if no lease ID is proposed. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. The lease ID is * required to be set with an access condition. * @return A String that represents the new lease ID. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final String changeLease(final String proposedLeaseId, final AccessCondition accessCondition) throws StorageException { return this.changeLease(proposedLeaseId, accessCondition, null, null); } /** * Changes the existing lease ID to the proposed lease Id with the specified access conditions, request options, * and operation context. * * @param proposedLeaseId * A String that represents the proposed lease ID for the new lease. This cannot be null. * * @param accessCondition * An {@link AccessCondition} object that represents the access conditions for the blob. The lease ID is * required to be set with an access condition. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client * ({@link CloudBlobClient}). * * @param opContext * An {@link OperationContext} object that represents the context for the current operation. The context * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * @return A String that represents the new lease ID. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public final String changeLease(final String proposedLeaseId, final AccessCondition accessCondition, BlobRequestOptions options, OperationContext opContext) throws StorageException { Utility.assertNotNull("proposedLeaseId", proposedLeaseId); Utility.assertNotNull("accessCondition", accessCondition); Utility.assertNotNullOrEmpty("leaseID", accessCondition.getLeaseID()); if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.changeLeaseImpl(proposedLeaseId, accessCondition, options), options.getRetryPolicyFactory(), opContext); } private final StorageRequest changeLeaseImpl( final String proposedLeaseId, final AccessCondition accessCondition, final BlobRequestOptions options) { final StorageRequest putRequest = new StorageRequest( options, this.getStorageUri()) { @Override public HttpURLConnection buildRequest(CloudBlobClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BlobRequest.leaseContainer(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, context, accessCondition, LeaseAction.CHANGE, null, proposedLeaseId, null); } @Override public void signRequest(HttpURLConnection connection, CloudBlobClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, 0L, context); } @Override public String preProcessResponse(CloudBlobContainer container, CloudBlobClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); return null; } container.updatePropertiesFromResponse(this.getConnection()); return BlobResponse.getLeaseID(this.getConnection()); } }; return putRequest; } /** * Gets information related to the storage account in which this container resides. * * @return A {@link AccountInformation} object for the given storage account. * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public AccountInformation downloadAccountInfo() throws StorageException { return this.downloadAccountInfo(null /* options */, null /* opContext */); } /** * Gets information related to the storage account in which this container resides. * * @param options * A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying * null will use the default request options from the associated service client ( * {@link CloudBlobClient}). * @param opContext * An {@link OperationContext} object that represents the context for the current operation. This object * is used to track requests to the storage service, and to provide additional runtime information about * the operation. * * @return A {@link AccountInformation} object for the given storage account. * * @throws StorageException * If a storage service error occurred. */ @DoesServiceRequest public AccountInformation downloadAccountInfo(BlobRequestOptions options, OperationContext opContext) throws StorageException { if (opContext == null) { opContext = new OperationContext(); } opContext.initialize(); options = BlobRequestOptions.populateAndApplyDefaults(options, BlobType.UNSPECIFIED, this.blobServiceClient); return ExecutionEngine.executeWithRetry(this.blobServiceClient, this, this.downloadAccountInformationImpl(options), options.getRetryPolicyFactory(), opContext); } protected StorageRequest downloadAccountInformationImpl( final RequestOptions options) { final StorageRequest headRequest = new StorageRequest( options, this.getStorageUri()) { @Override public void setRequestLocationMode() { this.setRequestLocationMode(RequestLocationMode.PRIMARY_OR_SECONDARY); } @Override public HttpURLConnection buildRequest(ServiceClient client, CloudBlobContainer container, OperationContext context) throws Exception { return BaseRequest.getAccountInfo(container.getTransformedAddress().getUri(this.getCurrentLocation()), options, null, context); } @Override public void signRequest(HttpURLConnection connection, ServiceClient client, OperationContext context) throws Exception { StorageRequest.signBlobQueueAndFileRequest(connection, client, -1, context); } @Override public AccountInformation preProcessResponse(CloudBlobContainer container, ServiceClient client, OperationContext context) throws Exception { if (this.getResult().getStatusCode() != HttpURLConnection.HTTP_OK) { this.setNonExceptionedRetryableFailure(true); } return BlobResponse.getAccountInformation(this.getConnection()); } }; return headRequest; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy