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

com.microsoft.azure.storage.CloudStorageAccount 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;

import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.microsoft.azure.storage.analytics.CloudAnalyticsClient;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.core.SR;
import com.microsoft.azure.storage.core.SharedAccessSignatureHelper;
import com.microsoft.azure.storage.core.StorageCredentialsHelper;
import com.microsoft.azure.storage.core.UriQueryBuilder;
import com.microsoft.azure.storage.core.Utility;
import com.microsoft.azure.storage.file.CloudFileClient;
import com.microsoft.azure.storage.queue.CloudQueue;
import com.microsoft.azure.storage.queue.CloudQueueClient;
import com.microsoft.azure.storage.table.CloudTable;
import com.microsoft.azure.storage.table.CloudTableClient;

/**
 * Represents a Microsoft Azure storage account.
 */
public final class CloudStorageAccount {
    /**
     * Represents the setting name for the account key.
     */
    protected static final String ACCOUNT_KEY_NAME = "AccountKey";

    /**
     * Represents the setting name for the token credential.
     */
    protected static final String ACCOUNT_TOKEN_NAME = "AccountToken";

    /**
     * Represents the setting name for the account name.
     */
    protected static final String ACCOUNT_NAME_NAME = "AccountName";

    /**
     * Represents the final terms of each root storage DNS name.
     */
    private static final String DNS_NAME_FORMAT = "%s.%s";
    
    /**
     * Represents the root storage DNS name.
     */
    private static final String DEFAULT_DNS = "core.windows.net";
    
    /**
     * The suffix appended to account in order to access secondary location for read only access.
     */
    private static final String SECONDARY_LOCATION_ACCOUNT_SUFFIX = "-secondary";
    
    /**
     * Represents the setting name for a custom storage endpoint suffix.
     */
    private static final String ENDPOINT_SUFFIX_NAME = "EndpointSuffix";

    /**
     * Represents the setting name for a custom blob storage endpoint.
     */
    protected static final String BLOB_ENDPOINT_NAME = "BlobEndpoint";

    /**
     * Represents the setting name for a custom blob storage secondary endpoint.
     */
    protected static final String BLOB_SECONDARY_ENDPOINT_NAME = "BlobSecondaryEndpoint";

    /**
     * The setting name for using the default storage endpoints with the specified protocol.
     */
    private static final String DEFAULT_ENDPOINTS_PROTOCOL_NAME = "DefaultEndpointsProtocol";

    /**
     * The format string for the primary endpoint.
     */
    private static final String DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT = "%s://%s:%s/%s";

    /**
     * The format string for the secondary endpoint.
     */
    private static final String DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT =
            DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT + SECONDARY_LOCATION_ACCOUNT_SUFFIX;

    /**
     * The setting name for specifying a development storage proxy Uri.
     */
    private static final String DEVELOPMENT_STORAGE_PROXY_URI_NAME = "DevelopmentStorageProxyUri";

    /**
     * The default account key for the development storage.
     */
    private static final String DEVSTORE_ACCOUNT_KEY = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";

    /**
     * The default account name for the development storage.
     */
    private static final String DEVSTORE_ACCOUNT_NAME = "devstoreaccount1";

    /**
     * Represents the setting name for a custom file endpoint.
     */
    private static final String FILE_ENDPOINT_NAME = "FileEndpoint";

    /**
     * Represents the setting name for a custom file secondary endpoint.
     */
    private static final String FILE_SECONDARY_ENDPOINT_NAME = "FileSecondaryEndpoint";

    /**
     * The format string for the primary endpoint.
     */
    private static final String PRIMARY_ENDPOINT_FORMAT = "%s://%s.%s";

    /**
     * The format string for the secondary endpoint
     */
    private static final String SECONDARY_ENDPOINT_FORMAT = "%s://%s%s.%s";

    /**
     * Represents the setting name for a custom queue endpoint.
     */
    protected static final String QUEUE_ENDPOINT_NAME = "QueueEndpoint";

    /**
     * Represents the setting name for a custom queue secondary endpoint.
     */
    protected static final String QUEUE_SECONDARY_ENDPOINT_NAME = "QueueSecondaryEndpoint";

    /**
     * Represents the setting name for a shared access key.
     */
    protected static final String SHARED_ACCESS_SIGNATURE_NAME = "SharedAccessSignature";

    /**
     * Represents the setting name for a custom table storage endpoint.
     */
    protected static final String TABLE_ENDPOINT_NAME = "TableEndpoint";

    /**
     * Represents the setting name for a custom table storage secondary endpoint.
     */
    protected static final String TABLE_SECONDARY_ENDPOINT_NAME = "TableSecondaryEndpoint";

    /**
     * The setting name for using the development storage.
     */
    private static final String USE_DEVELOPMENT_STORAGE_NAME = "UseDevelopmentStorage";
    
    /**
     * Returns a {@link CloudStorageAccount} object that represents the development storage credentials. Secondary
     * endpoints are enabled by default.
     * 
     * @return A {@link CloudStorageAccount} object for the development storage credentials.
     */
    public static CloudStorageAccount getDevelopmentStorageAccount() {
        try {
            return getDevelopmentStorageAccount(null);
        }
        catch (final URISyntaxException e) {
            // this won't happen since we know the standard development stororage uri is valid.
            return null;
        }
    }

    /**
     * Returns a {@link CloudStorageAccount} object that represents the development storage credentials, using the
     * specified proxy URI. Secondary endpoints are enabled by default.
     * 
     * @param proxyUri
     *            A java.net.URI object that represents the proxy endpoint to use. Specifying
     *            null will use the default http://127.0.0.1.
     * 
     * @return A {@link CloudStorageAccount} object for the development storage credentials.
     * 
     * @throws URISyntaxException
     *             If the resource URI is invalid.
     */
    public static CloudStorageAccount getDevelopmentStorageAccount(final URI proxyUri) throws URISyntaxException {
        String scheme;
        String host;
        if (proxyUri == null) {
            scheme = "http";
            host = "127.0.0.1";
        }
        else {
            scheme = proxyUri.getScheme();
            host = proxyUri.getHost();
        }

        StorageCredentials credentials = new StorageCredentialsAccountAndKey(DEVSTORE_ACCOUNT_NAME,
                DEVSTORE_ACCOUNT_KEY);

        URI blobPrimaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT, scheme, host,
                "10000", DEVSTORE_ACCOUNT_NAME));
        URI queuePrimaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT, scheme, host,
                "10001", DEVSTORE_ACCOUNT_NAME));
        URI tablePrimaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_PRIMARY_ENDPOINT_FORMAT, scheme, host,
                "10002", DEVSTORE_ACCOUNT_NAME));

        URI blobSecondaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT, scheme, host,
                "10000", DEVSTORE_ACCOUNT_NAME));
        URI queueSecondaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT, scheme, host,
                "10001", DEVSTORE_ACCOUNT_NAME));
        URI tableSecondaryEndpoint = new URI(String.format(DEVELOPMENT_STORAGE_SECONDARY_ENDPOINT_FORMAT, scheme, host,
                "10002", DEVSTORE_ACCOUNT_NAME));

        CloudStorageAccount account = new CloudStorageAccount(credentials, new StorageUri(blobPrimaryEndpoint,
                blobSecondaryEndpoint), new StorageUri(queuePrimaryEndpoint, queueSecondaryEndpoint), new StorageUri(
                tablePrimaryEndpoint, tableSecondaryEndpoint), null /* fileStorageUri */);

        account.isDevStoreAccount = true;

        return account;
    }

    /**
     * Parses a connection string and returns a cloud storage account created from the connection string.
     * 

* The connection string should be in the Azure * connection string format. *

* Note that while a connection string may include a SAS token, it is often easier to use the * {@link CloudBlobContainer#CloudBlobContainer(URI)}, {@link CloudQueue#CloudQueue(URI)}, * {@link CloudTable#CloudTable(URI)} constructors directly. To do this, create a * {@link StorageCredentialsSharedAccessSignature#StorageCredentialsSharedAccessSignature(String)} object with your * SAS token, use the {@link StorageCredentialsSharedAccessSignature#transformUri(URI)} method on the container, * queue, or table URI, and then use that URI to construct the object. * * @param connectionString * A String that represents the connection string to parse. * * @return A {@link CloudStorageAccount} object that represents the cloud storage account constructed from the * values provided in the connection string. * * @throws InvalidKeyException * If credentials in the connection string contain an invalid key. * @throws URISyntaxException * If the connection string specifies an invalid URI. */ public static CloudStorageAccount parse(final String connectionString) throws URISyntaxException, InvalidKeyException { if (connectionString == null || connectionString.length() == 0) { throw new IllegalArgumentException(SR.INVALID_CONNECTION_STRING); } // 1. Parse connection string in to key / value pairs final Map settings = Utility.parseAccountString(connectionString); // 2 Validate General Settings rules, // - only setting value per key // - setting must have value. for (final Entry entry : settings.entrySet()) { if (entry.getValue() == null || entry.getValue().equals(Constants.EMPTY_STRING)) { throw new IllegalArgumentException(SR.INVALID_CONNECTION_STRING); } } // 3. Validate scenario specific constraints CloudStorageAccount account = tryConfigureDevStore(settings); if (account != null) { return account; } account = tryConfigureServiceAccount(settings); if (account != null) { return account; } throw new IllegalArgumentException(SR.INVALID_CONNECTION_STRING); } /** * Gets the {@link StorageUri} using specified service, settings, and endpoint. * * @param settings * A java.util.Map of key/value pairs which represents * the connection settings. * @param service * A String that represents the service's base DNS name. * @param serviceEndpointName * The service endpoint name to check in settings. * @param serviceSecondaryEndpointName * The service secondary endpoint name to check in settings. * @param matchesAutomaticEndpointsSpec * Whether the settings match the automatic endpoints specification. * @return The {@link StorageUri}. * @throws URISyntaxException */ private static StorageUri getStorageUri( final Map settings, final String service, final String serviceEndpointName, final String serviceSecondaryEndpointName, final Boolean matchesAutomaticEndpointsSpec) throws URISyntaxException { String serviceEndpoint = settingOrDefault(settings, serviceEndpointName); String serviceSecondaryEndpoint = settingOrDefault(settings, serviceSecondaryEndpointName); if (serviceSecondaryEndpoint != null && serviceEndpoint != null) { return new StorageUri(new URI(serviceEndpoint), new URI(serviceSecondaryEndpoint)); } else if (serviceEndpoint != null) { return new StorageUri(new URI(serviceEndpoint)); } else if (matchesAutomaticEndpointsSpec) { final String scheme = settings.get(CloudStorageAccount.DEFAULT_ENDPOINTS_PROTOCOL_NAME); final String accountName = settings.get(CloudStorageAccount.ACCOUNT_NAME_NAME); final String endpointSuffix = settings.get(CloudStorageAccount.ENDPOINT_SUFFIX_NAME); return getDefaultStorageUri(scheme, accountName, getDNS(service, endpointSuffix)); } else { return null; } } /** * Gets the default {@link StorageUri} using the specified service, protocol and account name. * * @param scheme * The protocol to use. * @param accountName * The name of the storage account. * @param service * A String that represents the service's base DNS name. * @return The default {@link StorageUri}. */ private static StorageUri getDefaultStorageUri(final String scheme, final String accountName, final String service) throws URISyntaxException { if (Utility.isNullOrEmpty(scheme)) { throw new IllegalArgumentException(SR.SCHEME_NULL_OR_EMPTY); } if (Utility.isNullOrEmpty(accountName)) { throw new IllegalArgumentException(SR.ACCOUNT_NAME_NULL_OR_EMPTY); } URI primaryUri = new URI(String.format(PRIMARY_ENDPOINT_FORMAT, scheme, accountName, service)); URI secondaryUri = new URI( String.format(SECONDARY_ENDPOINT_FORMAT, scheme, accountName, SECONDARY_LOCATION_ACCOUNT_SUFFIX, service)); return new StorageUri(primaryUri, secondaryUri); } /** * This generates a domain name for the given service. * * @param service * the service to connect to * @param base * the suffix to use * @return the domain name */ private static String getDNS(String service, String base) { if (base == null) { base = DEFAULT_DNS; } return String.format(DNS_NAME_FORMAT, service, base); } /** * Evaluates connection settings and returns a CloudStorageAccount representing Development Storage. * * @param settings * A java.util.Map of key/value pairs which represents the connection settings. * @return A {@link CloudStorageAccount} object constructed from the values provided in the connection settings, or * null if * one cannot be constructed. * @throws URISyntaxException * if the connection settings contains an invalid URI */ private static CloudStorageAccount tryConfigureDevStore(final Map settings) throws URISyntaxException { if (matchesSpecification( settings, allRequired(USE_DEVELOPMENT_STORAGE_NAME), optional(DEVELOPMENT_STORAGE_PROXY_URI_NAME))) { if (!Boolean.parseBoolean(settings.get(USE_DEVELOPMENT_STORAGE_NAME))) { throw new IllegalArgumentException(SR.INVALID_CONNECTION_STRING_DEV_STORE_NOT_TRUE); } URI devStoreProxyUri = null; if (settings.containsKey(DEVELOPMENT_STORAGE_PROXY_URI_NAME)) { devStoreProxyUri = new URI(settings.get(DEVELOPMENT_STORAGE_PROXY_URI_NAME)); } return getDevelopmentStorageAccount(devStoreProxyUri); } else { return null; } } private interface ConnectionStringFilter { Map apply(Map settings); } private static ConnectionStringFilter allRequired(final String... settingNames) { return new ConnectionStringFilter() { @Override public Map apply(Map settings) { final Map result = new HashMap(settings); for (final String settingName : settingNames) { if (result.containsKey(settingName)) { result.remove(settingName); } else { return null; } } return result; } }; } private static ConnectionStringFilter optional(final String... settingNames) { return new ConnectionStringFilter() { @Override public Map apply(Map settings) { final Map result = new HashMap(settings); for (final String settingName : settingNames) { if (result.containsKey(settingName)) { result.remove(settingName); } } return result; } }; } private static ConnectionStringFilter atLeastOne(final String... settingNames) { return new ConnectionStringFilter() { @Override public Map apply(Map settings) { final Map result = new HashMap(settings); Boolean foundOne = false; for (final String settingName : settingNames) { if (result.containsKey(settingName)) { result.remove(settingName); foundOne = true; } } return foundOne ? result : null; } }; } private static ConnectionStringFilter none(final String... settingNames) { return new ConnectionStringFilter() { @Override public Map apply(Map settings) { final Map result = new HashMap(settings); Boolean foundOne = false; for (final String settingName : settingNames) { if (result.containsKey(settingName)) { result.remove(settingName); foundOne = true; } } return foundOne ? null : result; } }; } private static ConnectionStringFilter matchesAll(final ConnectionStringFilter... filters) { return new ConnectionStringFilter() { @Override public Map apply(Map settings) { Map result = new HashMap(settings); for (final ConnectionStringFilter filter : filters) { if (result == null) { break; } result = filter.apply(result); } return result; } }; } private static ConnectionStringFilter matchesOne(final ConnectionStringFilter... filters) { return new ConnectionStringFilter() { @Override public Map apply(Map settings) { Map matchResult = null; for (final ConnectionStringFilter filter : filters) { Map result = filter.apply(new HashMap(settings)); if (result != null) { if (matchResult == null) { matchResult = result; } else { return null; } } } return matchResult; } }; } private static ConnectionStringFilter matchesExactly(final ConnectionStringFilter filter) { return new ConnectionStringFilter() { @Override public Map apply(Map settings) { Map result = new HashMap(settings); result = filter.apply(result); if (result == null || !result.isEmpty()) { return null; } else { return result; } } }; } private static ConnectionStringFilter validCredentials = matchesOne( matchesAll(allRequired(ACCOUNT_NAME_NAME, ACCOUNT_KEY_NAME), none(SHARED_ACCESS_SIGNATURE_NAME)), matchesAll(allRequired(SHARED_ACCESS_SIGNATURE_NAME), optional(ACCOUNT_NAME_NAME), none(ACCOUNT_KEY_NAME)), none(ACCOUNT_NAME_NAME, ACCOUNT_KEY_NAME, SHARED_ACCESS_SIGNATURE_NAME) ); private static Boolean matchesSpecification( Map settings, ConnectionStringFilter... constraints) { for (ConnectionStringFilter constraint: constraints) { Map remainingSettings = constraint.apply(settings); if (remainingSettings == null) { return false; } else { settings = remainingSettings; } } if (settings.isEmpty()) { return true; } return false; } private static Boolean isValidEndpointPair(String primary, String secondary) { return (primary != null) || (/* primary is null, and... */ secondary == null); } private static String settingOrDefault(Map settings, String key) { return settings.containsKey(key) ? settings.get(key) : null; } /** * Evaluates connection settings and configures a CloudStorageAccount accordingly. * * @param settings * A java.util.Map of key/value pairs which represents * the connection settings. * @return A {@link CloudStorageAccount} represented by the settings. * @throws URISyntaxException * if the connectionString specifies an invalid URI. * @throws InvalidKeyException * if credentials in the connection settings contain an invalid key. */ private static CloudStorageAccount tryConfigureServiceAccount(final Map settings) throws URISyntaxException, InvalidKeyException { ConnectionStringFilter endpointsOptional = optional( BLOB_ENDPOINT_NAME, BLOB_SECONDARY_ENDPOINT_NAME, QUEUE_ENDPOINT_NAME, QUEUE_SECONDARY_ENDPOINT_NAME, TABLE_ENDPOINT_NAME, TABLE_SECONDARY_ENDPOINT_NAME, FILE_ENDPOINT_NAME, FILE_SECONDARY_ENDPOINT_NAME ); ConnectionStringFilter primaryEndpointRequired = atLeastOne( BLOB_ENDPOINT_NAME, QUEUE_ENDPOINT_NAME, TABLE_ENDPOINT_NAME, FILE_ENDPOINT_NAME ); ConnectionStringFilter secondaryEndpointsOptional = optional( BLOB_SECONDARY_ENDPOINT_NAME, QUEUE_SECONDARY_ENDPOINT_NAME, TABLE_SECONDARY_ENDPOINT_NAME, FILE_SECONDARY_ENDPOINT_NAME ); ConnectionStringFilter automaticEndpointsMatchSpec = matchesExactly(matchesAll( matchesOne( matchesAll(allRequired(ACCOUNT_KEY_NAME)), // Key + Name, Endpoints optional allRequired(SHARED_ACCESS_SIGNATURE_NAME) // SAS + Name, Endpoints optional ), allRequired(ACCOUNT_NAME_NAME), // Name required to automatically create URIs endpointsOptional, optional(DEFAULT_ENDPOINTS_PROTOCOL_NAME, ENDPOINT_SUFFIX_NAME) )); ConnectionStringFilter explicitEndpointsMatchSpec = matchesExactly(matchesAll( // Any Credentials, Endpoints must be explicitly declared validCredentials, primaryEndpointRequired, secondaryEndpointsOptional )); Boolean matchesAutomaticEndpointsSpec = matchesSpecification(settings, automaticEndpointsMatchSpec); Boolean matchesExplicitEndpointsSpec = matchesSpecification(settings, explicitEndpointsMatchSpec); if (matchesAutomaticEndpointsSpec || matchesExplicitEndpointsSpec) { if (matchesAutomaticEndpointsSpec && !settings.containsKey(DEFAULT_ENDPOINTS_PROTOCOL_NAME)) { settings.put(DEFAULT_ENDPOINTS_PROTOCOL_NAME, "https"); } String blobEndpoint = settingOrDefault(settings, BLOB_ENDPOINT_NAME); String queueEndpoint = settingOrDefault(settings, QUEUE_ENDPOINT_NAME); String tableEndpoint = settingOrDefault(settings, TABLE_ENDPOINT_NAME); String fileEndpoint = settingOrDefault(settings, FILE_ENDPOINT_NAME); String blobSecondaryEndpoint = settingOrDefault(settings, BLOB_SECONDARY_ENDPOINT_NAME); String queueSecondaryEndpoint = settingOrDefault(settings, QUEUE_SECONDARY_ENDPOINT_NAME); String tableSecondaryEndpoint = settingOrDefault(settings, TABLE_SECONDARY_ENDPOINT_NAME); String fileSecondaryEndpoint = settingOrDefault(settings, FILE_SECONDARY_ENDPOINT_NAME); // if secondary is specified, primary must also be specified if ( isValidEndpointPair(blobEndpoint, blobSecondaryEndpoint) && isValidEndpointPair(queueEndpoint, queueSecondaryEndpoint) && isValidEndpointPair(tableEndpoint, tableSecondaryEndpoint) && isValidEndpointPair(fileEndpoint, fileSecondaryEndpoint) ) { CloudStorageAccount accountInformation = new CloudStorageAccount( StorageCredentials.tryParseCredentials(settings), getStorageUri(settings, SR.BLOB, BLOB_ENDPOINT_NAME, BLOB_SECONDARY_ENDPOINT_NAME, matchesAutomaticEndpointsSpec), getStorageUri(settings, SR.QUEUE, QUEUE_ENDPOINT_NAME, QUEUE_SECONDARY_ENDPOINT_NAME, matchesAutomaticEndpointsSpec), getStorageUri(settings, SR.TABLE, TABLE_ENDPOINT_NAME, TABLE_SECONDARY_ENDPOINT_NAME, matchesAutomaticEndpointsSpec), getStorageUri(settings, SR.FILE, FILE_ENDPOINT_NAME, FILE_SECONDARY_ENDPOINT_NAME, matchesAutomaticEndpointsSpec) ); accountInformation.isBlobEndpointDefault = blobEndpoint == null; accountInformation.isFileEndpointDefault = fileEndpoint == null; accountInformation.isQueueEndpointDefault = queueEndpoint == null; accountInformation.isTableEndpointDefault = tableEndpoint == null; accountInformation.endpointSuffix = settingOrDefault(settings, ENDPOINT_SUFFIX_NAME); accountInformation.accountName = settingOrDefault(settings, ACCOUNT_NAME_NAME); return accountInformation; } } return null; } /** * The explicit endpoint suffix if one other than the default is needed. Null otherwise. */ private String endpointSuffix; /** * The internal Blob StorageUri. */ private final StorageUri blobStorageUri; /** * The internal file StorageUri. */ private final StorageUri fileStorageUri; /** * The internal queue StorageUri. */ private final StorageUri queueStorageUri; /** * The internal table StorageUri. */ private final StorageUri tableStorageUri; /** * The internal Storage Credentials. */ private StorageCredentials credentials; /** * The internal account name. */ private String accountName; /** * Internal flag storing true if the blob endpoint was created using default settings. * False if the caller specified the blob endpoint explicitly. */ private boolean isBlobEndpointDefault = false; /** * Internal flag storing true if the file endpoint was created using default settings. * False if the caller specified the file endpoint explicitly. */ private boolean isFileEndpointDefault = false; /** * Internal flag storing true if the queue endpoint was created using default settings. * False if the caller specified the queue endpoint explicitly. */ private boolean isQueueEndpointDefault = false; /** * Internal flag storing true if the table endpoint was created using default settings. * False if the caller specified the table endpoint explicitly. */ private boolean isTableEndpointDefault = false; /** * Internal flag storing true if this is a dev store account created by one of the * getDevelopmentStorageAccount methods, either called directly or by parsing a * connection string with the UseDevelopmentStorage flag. False otherwise. */ private boolean isDevStoreAccount = false; /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials. *

* With this constructor, the CloudStorageAccount object is constructed using the * default HTTP storage service endpoints. The default HTTP storage service endpoints are * http://myaccount.blob.core.windows.net, * http://myaccount.queue.core.windows.net, * http://myaccount.table.core.windows.net, and * http://myaccount.file.core.windows.net, where * myaccount is the name of your storage account. *

* The credentials provided when constructing the CloudStorageAccount object * are used to authenticate all further requests against resources that are accessed via * the CloudStorageAccount object or a client object created from it. * A client object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * * @throws URISyntaxException * If storageCredentials specify an invalid account name. */ public CloudStorageAccount(final StorageCredentials storageCredentials) throws URISyntaxException { // Protocol defaults to HTTP unless otherwise specified this(storageCredentials, false, null); } /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials and the default service endpoints, using HTTP or HTTPS as specified. *

* With this constructor, the CloudStorageAccount object is constructed using * the default storage service endpoints. The default storage service endpoints are: * [http|https]://myaccount.blob.core.windows.net; * [http|https]://myaccount.queue.core.windows.net; * [http|https]://myaccount.table.core.windows.net; and * [http|https]://myaccount.file.core.windows.net, * where myaccount is the name of your storage account. Access to the cloud * storage account may be via HTTP or HTTPS, as specified by the useHttps parameter. *

* The credentials provided when constructing the CloudStorageAccount object * are used to authenticate all further requests against resources that are accessed via * the CloudStorageAccount object or a client object created from it. A client * object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * @param useHttps * true to use HTTPS to connect to the storage service endpoints; * otherwise, false. * * @throws URISyntaxException * If storageCredentials specify an invalid account name. */ public CloudStorageAccount(final StorageCredentials storageCredentials, final boolean useHttps) throws URISyntaxException { this (storageCredentials, useHttps, null); } /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials. *

* With this constructor, the CloudStorageAccount object is constructed using the * given HTTP storage service endpoint suffix (if any, otherwise the default is used). * * The credentials provided when constructing the CloudStorageAccount object * are used to authenticate all further requests against resources that are accessed via * the CloudStorageAccount object or a client object created from it. * A client object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * @param useHttps * true to use HTTPS to connect to the storage service endpoints; * otherwise, false. * @param endpointSuffix * A String that represents the endpointSuffix to use, if any. * * @throws URISyntaxException * If storageCredentials specify an invalid account name. */ public CloudStorageAccount( final StorageCredentials storageCredentials, final boolean useHttps, final String endpointSuffix) throws URISyntaxException { this(storageCredentials, useHttps, endpointSuffix, null); } /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials. *

* With this constructor, the CloudStorageAccount object is constructed using the * given HTTP storage service endpoint suffix (if any, otherwise the default is used). * * The credentials provided when constructing the CloudStorageAccount object * are used to authenticate all further requests against resources that are accessed via * the CloudStorageAccount object or a client object created from it. * A client object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * @param useHttps * true to use HTTPS to connect to the storage service endpoints; * otherwise, false. * @param endpointSuffix * A String that represents the endpointSuffix to use, if any. * @param accountName * A String that contains the account name. This will be used in place of a * null {@link StorageCredentials#getAccountName()}, but the two must match if * both are not null. * * @throws URISyntaxException * If storageCredentials specify an invalid account name. */ public CloudStorageAccount( final StorageCredentials storageCredentials, final boolean useHttps, final String endpointSuffix, String accountName) throws URISyntaxException { Utility.assertNotNull("storageCredentials", storageCredentials); if (Utility.isNullOrEmpty(accountName)) { accountName = storageCredentials.getAccountName(); } else if (!Utility.isNullOrEmpty(storageCredentials.getAccountName()) && !accountName.equals(storageCredentials.getAccountName())) { throw new IllegalArgumentException(SR.ACCOUNT_NAME_MISMATCH); } String protocol = useHttps ? Constants.HTTPS : Constants.HTTP; this.credentials = storageCredentials; this.blobStorageUri = getDefaultStorageUri(protocol, accountName, getDNS(SR.BLOB, endpointSuffix)); this.fileStorageUri = getDefaultStorageUri(protocol, accountName, getDNS(SR.FILE, endpointSuffix)); this.queueStorageUri = getDefaultStorageUri(protocol, accountName, getDNS(SR.QUEUE, endpointSuffix)); this.tableStorageUri = getDefaultStorageUri(protocol, accountName, getDNS(SR.TABLE, endpointSuffix)); this.endpointSuffix = endpointSuffix; this.isBlobEndpointDefault = true; this.isFileEndpointDefault = true; this.isQueueEndpointDefault = true; this.isTableEndpointDefault = true; } /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials and service endpoints. *

* Use this constructor to construct a CloudStorageAccount object using custom * endpoints, in the case where you've configured a custom domain name for your storage account. *

* The credentials provided when constructing the CloudStorageAccount object * are used to authenticate all further requests against resources that are accessed via * the CloudStorageAccount object or a client object created from it. A * client object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * @param blobEndpoint * A java.net.URI object that represents the Blob service endpoint. * @param queueEndpoint * A java.net.URI object that represents the Queue service endpoint. * @param tableEndpoint * A java.net.URI object that represents the Table service endpoint. */ public CloudStorageAccount(final StorageCredentials storageCredentials, final URI blobEndpoint, final URI queueEndpoint, final URI tableEndpoint) { this(storageCredentials, new StorageUri(blobEndpoint), new StorageUri(queueEndpoint), new StorageUri(tableEndpoint), null); } /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials and service endpoints. *

* Use this constructor to construct a CloudStorageAccount object using custom * endpoints, in the case where you've configured a custom domain name for your storage account. *

* The credentials provided when constructing the CloudStorageAccount object * are used to authenticate all further requests against resources that are accessed via * the CloudStorageAccount object or a client object created from it. A client * object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * @param blobEndpoint * A java.net.URI object that represents the Blob service endpoint. * @param queueEndpoint * A java.net.URI object that represents the Queue service endpoint. * @param tableEndpoint * A java.net.URI object that represents the Table service endpoint. * @param fileEndpoint * A java.net.URI object that represents the File service endpoint. */ public CloudStorageAccount(final StorageCredentials storageCredentials, final URI blobEndpoint, final URI queueEndpoint, final URI tableEndpoint, final URI fileEndpoint) { this(storageCredentials, new StorageUri(blobEndpoint), new StorageUri(queueEndpoint), new StorageUri(tableEndpoint), new StorageUri(fileEndpoint)); } /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials and service endpoints. *

* Use this constructor to construct a CloudStorageAccount object using custom * endpoints, in the case where you've configured a custom domain name for your storage account. *

* The credentials provided when constructing the CloudStorageAccount object * are used to authenticate all further requests against resources that are accessed via * the CloudStorageAccount object or a client object created from it. A client * object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * @param blobStorageUri * A {@link StorageUri} object that represents the Blob service endpoint. * @param queueStorageUri * A {@link StorageUri} object that represents the Queue service endpoint. * @param tableStorageUri * A {@link StorageUri} object that represents the Table service endpoint. */ public CloudStorageAccount(final StorageCredentials storageCredentials, final StorageUri blobStorageUri, final StorageUri queueStorageUri, final StorageUri tableStorageUri) { this(storageCredentials, blobStorageUri, queueStorageUri, tableStorageUri, null); } /** * Creates an instance of the CloudStorageAccount class using the specified * account credentials and service endpoints. *

* Use this constructor to construct a CloudStorageAccount object using custom * endpoints, in the case where you've configured a custom domain name for your storage account. *

* The credentials provided when constructing the CloudStorageAccount object are * used to authenticate all further requests against resources that are accessed via the * CloudStorageAccount object or a client object created from it. * A client object may be a {@link CloudBlobClient} object. * * @param storageCredentials * A {@link StorageCredentials} object that represents the storage credentials * to use to authenticate this account. * @param blobStorageUri * A {@link StorageUri} object that represents the Blob service endpoint. * @param queueStorageUri * A {@link StorageUri} object that represents the Queue service endpoint. * @param tableStorageUri * A {@link StorageUri} object that represents the Table service endpoint. * @param fileStorageUri * A {@link StorageUri} object that represents the File service endpoint. */ public CloudStorageAccount( final StorageCredentials storageCredentials, final StorageUri blobStorageUri, final StorageUri queueStorageUri, final StorageUri tableStorageUri, final StorageUri fileStorageUri) { this.credentials = storageCredentials; this.blobStorageUri = blobStorageUri; this.fileStorageUri = fileStorageUri; this.queueStorageUri = queueStorageUri; this.tableStorageUri = tableStorageUri; this.endpointSuffix = null; } /** * Creates a new Analytics service client. * * @return An analytics client object that uses the Blob and Table service endpoints. */ public CloudAnalyticsClient createCloudAnalyticsClient() { if (this.getBlobStorageUri() == null) { throw new IllegalArgumentException(SR.BLOB_ENDPOINT_NOT_CONFIGURED); } if (this.getTableStorageUri() == null) { throw new IllegalArgumentException(SR.TABLE_ENDPOINT_NOT_CONFIGURED); } if (this.credentials == null) { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } return new CloudAnalyticsClient(this.getBlobStorageUri(), this.getTableStorageUri(), this.getCredentials()); } /** * Creates a new Blob service client. * * @return A {@link CloudBlobClient} that represents the cloud Blob client. * */ public CloudBlobClient createCloudBlobClient() { if (this.getBlobStorageUri() == null) { throw new IllegalArgumentException(SR.BLOB_ENDPOINT_NOT_CONFIGURED); } if (this.credentials == null) { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } return new CloudBlobClient(this.getBlobStorageUri(), this.getCredentials()); } /** * Creates a new File service client. * * @return A {@link CloudFileClient} that represents the cloud File client. * */ public CloudFileClient createCloudFileClient() { if (this.getFileStorageUri() == null) { throw new IllegalArgumentException(SR.FILE_ENDPOINT_NOT_CONFIGURED); } if (this.credentials == null) { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } if (!StorageCredentialsHelper.canCredentialsGenerateClient(this.credentials)) { throw new IllegalArgumentException(SR.CREDENTIALS_CANNOT_SIGN_REQUEST); } return new CloudFileClient(this.getFileStorageUri(), this.getCredentials()); } /** * Creates a new Queue service client. * * @return A client object that uses the Queue service endpoint. */ public CloudQueueClient createCloudQueueClient() { if (this.getQueueStorageUri() == null) { throw new IllegalArgumentException(SR.QUEUE_ENDPOINT_NOT_CONFIGURED); } if (this.credentials == null) { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } if (!StorageCredentialsHelper.canCredentialsGenerateClient(this.credentials)) { throw new IllegalArgumentException(SR.CREDENTIALS_CANNOT_SIGN_REQUEST); } return new CloudQueueClient(this.getQueueStorageUri(), this.getCredentials()); } /** * Creates a new Table service client. * * @return A client object that uses the Table service endpoint. */ public CloudTableClient createCloudTableClient() { if (this.getTableStorageUri() == null) { throw new IllegalArgumentException(SR.TABLE_ENDPOINT_NOT_CONFIGURED); } if (this.credentials == null) { throw new IllegalArgumentException(SR.MISSING_CREDENTIALS); } if (!StorageCredentialsHelper.canCredentialsGenerateClient(this.credentials)) { throw new IllegalArgumentException(SR.CREDENTIALS_CANNOT_SIGN_REQUEST); } return new CloudTableClient(this.getTableStorageUri(), this.getCredentials()); } /** * Returns the endpoint for the Blob service for the storage account. This method is not supported when using shared * access signature credentials. * * @return A java.net.URI object that represents the Blob endpoint associated with this account. */ public URI getBlobEndpoint() { if (this.blobStorageUri == null) { return null; } return this.blobStorageUri.getPrimaryUri(); } /** * Returns the endpoint for the Blob service for the storage account. This method is not supported when using shared * access signature credentials. * * @return A {@link StorageUri} object that represents the Blob endpoint associated with this account. */ public StorageUri getBlobStorageUri() { return this.blobStorageUri; } /** * Returns the credentials for the storage account. * * @return A {@link StorageCredentials} object that represents the credentials for this storage account. */ public StorageCredentials getCredentials() { return this.credentials; } /** * If an endpoint suffix was specified, return it * @return the endpoint suffix */ public String getEndpointSuffix() { return this.endpointSuffix; } /** * Returns the endpoint for the File service for the storage account. This method is not supported when using shared * access signature credentials. * * @return A java.net.URI object that represents the File endpoint associated with this account. */ public URI getFileEndpoint() { if (this.fileStorageUri == null) { return null; } return this.fileStorageUri.getPrimaryUri(); } /** * Returns the endpoint for the File service for the storage account. This method is not supported when using shared * access signature credentials. * * @return A {@link StorageUri} object that represents the File endpoint associated with this account. */ public StorageUri getFileStorageUri() { return this.fileStorageUri; } /** * Returns the endpoint for the Queue service for the storage account. * * @return A java.net.URI object that represents the queue endpoint associated with this account. */ public URI getQueueEndpoint() { if (this.queueStorageUri == null) { return null; } return this.queueStorageUri.getPrimaryUri(); } /** * Returns the endpoint for the Queue service for the storage account. * * @return A {@link StorageUri} object that represents the Queue endpoint associated with this account. */ public StorageUri getQueueStorageUri() { return this.queueStorageUri; } /** * Returns the endpoint for the Table service for the storage account. * * @return A {@link StorageUri} object that represents the Table endpoint associated with this account. */ public URI getTableEndpoint() { if (this.tableStorageUri == null) { return null; } return this.tableStorageUri.getPrimaryUri(); } /** * Returns the endpoint for the Table service for the storage account. * * @return A java.net.URI object that represents the Table endpoint associated with this account. */ public StorageUri getTableStorageUri() { return this.tableStorageUri; } /** * Returns a shared access signature for the account. * * @param policy * A {@link SharedAccessAccountPolicy} specifying the access policy for the shared access signature. * * @return The query string returned includes the leading question mark. * @throws StorageException * If a storage service error occurred. * @throws InvalidKeyException * If the key is invalid. */ public String generateSharedAccessSignature(SharedAccessAccountPolicy policy) throws InvalidKeyException, StorageException { if (!StorageCredentialsHelper.canCredentialsSignRequest(this.getCredentials())) { throw new IllegalArgumentException(SR.CANNOT_CREATE_SAS_WITHOUT_ACCOUNT_KEY); } final String sig = SharedAccessSignatureHelper.generateSharedAccessSignatureHashForAccount( this.credentials.getAccountName(), policy, this.getCredentials()); final UriQueryBuilder sasBuilder = SharedAccessSignatureHelper.generateSharedAccessSignatureForAccount(policy, sig); return sasBuilder.toString(); } /** * Returns a connection string for this storage account, without sensitive data. * * @return A String that represents the connection string for this storage account, without sensitive * data. */ @Override public String toString() { return this.toString(false); } /** * Returns a connection string for this storage account, optionally with sensitive data. * * @param exportSecrets * true to include sensitive data in the string; * otherwise, false. * @return A String that represents the connection string for this storage account, * optionally with sensitive data. */ public String toString(final boolean exportSecrets) { final List values = new ArrayList(); if (this.isDevStoreAccount) { values.add(String.format("%s=true", USE_DEVELOPMENT_STORAGE_NAME)); if (!this.getBlobEndpoint().toString().equals("http://127.0.0.1:10000/devstoreaccount1")) { values.add(String.format("%s=%s://%s/", DEVELOPMENT_STORAGE_PROXY_URI_NAME, this.getBlobEndpoint().getScheme(), this.getBlobEndpoint().getHost())); } } else { final String attributeFormat = "%s=%s"; boolean addDefault = false; if (this.endpointSuffix != null) { values.add(String.format(attributeFormat, ENDPOINT_SUFFIX_NAME, this.endpointSuffix)); } if (this.getBlobStorageUri() != null) { if (this.isBlobEndpointDefault) { addDefault = true; } else { values.add(String.format(attributeFormat, BLOB_ENDPOINT_NAME, this.getBlobEndpoint())); } } if (this.getQueueStorageUri() != null) { if (this.isQueueEndpointDefault) { addDefault = true; } else { values.add(String.format(attributeFormat, QUEUE_ENDPOINT_NAME, this.getQueueEndpoint())); } } if (this.getTableStorageUri() != null) { if (this.isTableEndpointDefault) { addDefault = true; } else { values.add(String.format(attributeFormat, TABLE_ENDPOINT_NAME, this.getTableEndpoint())); } } if (this.getFileStorageUri() != null) { if (this.isFileEndpointDefault) { addDefault = true; } else { values.add(String.format(attributeFormat, FILE_ENDPOINT_NAME, this.getFileEndpoint())); } } if (addDefault) { values.add(String.format(attributeFormat, DEFAULT_ENDPOINTS_PROTOCOL_NAME, this.getBlobEndpoint().getScheme())); } if (this.getCredentials() != null) { values.add(this.getCredentials().toString(exportSecrets)); } if (this.accountName != null && (this.getCredentials() != null ? this.getCredentials().getAccountName() == null : true)) { values.add(String.format(attributeFormat, ACCOUNT_NAME_NAME, this.accountName)); } } final StringBuilder returnString = new StringBuilder(); for (final String val : values) { returnString.append(val); returnString.append(';'); } // Remove trailing ';' if (values.size() > 0) { returnString.deleteCharAt(returnString.length() - 1); } return returnString.toString(); } /** * Sets the StorageCredentials to use with this account. Warning: for internal use only, * as updating the credentials to a new account can invalidate pre-existing objects. * * @param credentials * the credentials to set */ protected void setCredentials(final StorageCredentials credentials) { this.credentials = credentials; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy