예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FileServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public FileServiceClient(string connectionString, FileClientOptions options)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            _uri      = conn.FileEndpoint;
            _pipeline = (options ?? new FileClientOptions()).Build(conn.Credentials);
        }
예제 #2
0
 private void SetConnectionString(string connection)
 {
     Debug.Assert(!string.IsNullOrEmpty(Stage));
     StorageAccount       = CloudStorageAccount.Parse(connection);
     CosmosStorageAccount = Microsoft.Azure.Cosmos.Table.CloudStorageAccount.Parse(connection);
     StorageCredentials   = (StorageSharedKeyCredential)StorageConnectionString.Parse(connection).Credentials;
 }
        public void DevelopmentStorageAccount()
        {
            var devstoreAccount = StorageConnectionString.DevelopmentStorageAccount;

            Assert.AreEqual(new Uri("http://127.0.0.1:10000/devstoreaccount1"), devstoreAccount.BlobEndpoint);
            Assert.AreEqual(new Uri("http://127.0.0.1:10001/devstoreaccount1"), devstoreAccount.QueueEndpoint);
            Assert.AreEqual(new Uri("http://127.0.0.1:10002/devstoreaccount1"), devstoreAccount.TableEndpoint);
            Assert.AreEqual(new Uri("http://127.0.0.1:10000/devstoreaccount1"), devstoreAccount.BlobStorageUri.PrimaryUri);
            Assert.AreEqual(new Uri("http://127.0.0.1:10001/devstoreaccount1"), devstoreAccount.QueueStorageUri.PrimaryUri);
            Assert.AreEqual(new Uri("http://127.0.0.1:10002/devstoreaccount1"), devstoreAccount.TableStorageUri.PrimaryUri);
            Assert.AreEqual(new Uri("http://127.0.0.1:10000/devstoreaccount1-secondary"), devstoreAccount.BlobStorageUri.SecondaryUri);
            Assert.AreEqual(new Uri("http://127.0.0.1:10001/devstoreaccount1-secondary"), devstoreAccount.QueueStorageUri.SecondaryUri);
            Assert.AreEqual(new Uri("http://127.0.0.1:10002/devstoreaccount1-secondary"), devstoreAccount.TableStorageUri.SecondaryUri);
            Assert.IsNull(devstoreAccount.FileStorageUri.PrimaryUri);
            Assert.IsNull(devstoreAccount.FileStorageUri.SecondaryUri);

            var devstoreAccountToStringWithSecrets = devstoreAccount.ToString(true);
            var testAccount = StorageConnectionString.Parse(devstoreAccountToStringWithSecrets);

            this.AccountsAreEqual(testAccount, devstoreAccount);
            if (!StorageConnectionString.TryParse(devstoreAccountToStringWithSecrets, out _))
            {
                Assert.Fail("Expected TryParse success.");
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="QueueServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public QueueServiceClient(string connectionString, QueueClientOptions options)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            this._uri      = conn.QueueEndpoint;
            this._pipeline = (options ?? new QueueClientOptions()).Build(conn.Credentials);
        }
        public void AnonymousRoundtrip()
        {
            var accountString = "BlobEndpoint=http://blobs/";

            Assert.AreEqual(accountString, StorageConnectionString.Parse(accountString).ToString(true));

            var account = new StorageConnectionString(null, (new Uri("http://blobs/"), default), (default, default), (default, default));
        public void EndpointSuffixWithHttps()
        {
            const string TestEndpointSuffix = "fake.endpoint.suffix";

            var conn = StorageConnectionString.Parse(
                String.Format(
                    "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2};",
                    TestConfigurations.DefaultTargetTenant.AccountName,
                    TestConfigurations.DefaultTargetTenant.AccountKey,
                    TestEndpointSuffix));

            Assert.AreEqual(conn.BlobEndpoint,
                            new Uri(String.Format("https://{0}.blob.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));
            Assert.AreEqual(conn.QueueEndpoint,
                            new Uri(String.Format("https://{0}.queue.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));
            Assert.AreEqual(conn.TableEndpoint,
                            new Uri(String.Format("https://{0}.table.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));
            Assert.AreEqual(conn.FileEndpoint,
                            new Uri(String.Format("https://{0}.file.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));
            Assert.AreEqual(conn.BlobStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.blob.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));
            Assert.AreEqual(conn.QueueStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.queue.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));
            Assert.AreEqual(conn.TableStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.table.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));
            Assert.AreEqual(conn.FileStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.file.{1}", TestConfigurations.DefaultTargetTenant.AccountName, TestEndpointSuffix)));

            var storageConnectionStringToStringWithSecrets = conn.ToString(true);
            var testAccount = StorageConnectionString.Parse(storageConnectionStringToStringWithSecrets);

            this.AccountsAreEqual(testAccount, conn);
        }
        public void DefaultStorageAccountWithHttps()
        {
            var cred = new SharedKeyCredentials(TestConfigurations.DefaultTargetTenant.AccountName, TestConfigurations.DefaultTargetTenant.AccountKey);
            var conn = new StorageConnectionString(cred, true);

            Assert.AreEqual(conn.BlobEndpoint,
                            new Uri(String.Format("https://{0}.blob.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));
            Assert.AreEqual(conn.QueueEndpoint,
                            new Uri(String.Format("https://{0}.queue.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));
            Assert.AreEqual(conn.TableEndpoint,
                            new Uri(String.Format("https://{0}.table.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));
            Assert.AreEqual(conn.FileEndpoint,
                            new Uri(String.Format("https://{0}.file.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));
            Assert.AreEqual(conn.BlobStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.blob.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));
            Assert.AreEqual(conn.QueueStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.queue.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));
            Assert.AreEqual(conn.TableStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.table.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));
            Assert.AreEqual(conn.FileStorageUri.SecondaryUri,
                            new Uri(String.Format("https://{0}-secondary.file.core.windows.net", TestConfigurations.DefaultTargetTenant.AccountName)));

            var storageConnectionStringToStringWithSecrets = conn.ToString(true);
            var testAccount = StorageConnectionString.Parse(storageConnectionStringToStringWithSecrets);

            this.AccountsAreEqual(testAccount, conn);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="BlobServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public BlobServiceClient(string connectionString, BlobClientOptions options)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            _uri = conn.BlobEndpoint;
            options ??= new BlobClientOptions();
            _pipeline = options.Build(conn.Credentials);
        }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ShareServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public ShareServiceClient(string connectionString, ShareClientOptions options)
        {
            options ??= new ShareClientOptions();
            var conn = StorageConnectionString.Parse(connectionString);

            _uri               = conn.FileEndpoint;
            _pipeline          = options.Build(conn.Credentials);
            _clientDiagnostics = new ClientDiagnostics(options);
        }
예제 #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="QueueServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public QueueServiceClient(string connectionString, QueueClientOptions options)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            _uri = conn.QueueEndpoint;
            options ??= new QueueClientOptions();
            _pipeline          = options.Build(conn.Credentials);
            _clientDiagnostics = new ClientDiagnostics(options);
        }
        public void AnonymousRoundtrip()
        {
            var accountString = "BlobEndpoint=http://blobs/";

            Assert.AreEqual(accountString, StorageConnectionString.Parse(accountString).ToString(true));

            var account = new StorageConnectionString(null, new Uri("http://blobs/"), null, null, null);

            this.AccountsAreEqual(account, StorageConnectionString.Parse(account.ToString(true)));
        }
예제 #12
0
        private void SetConnectionString(string connection)
        {
            if (string.IsNullOrWhiteSpace(connection))
            {
                throw new Exception("Azure connection cannot be null or empty");
            }

            CosmosStorageAccount = Microsoft.Azure.Cosmos.Table.CloudStorageAccount.Parse(connection);
            StorageCredentials   = (StorageSharedKeyCredential)StorageConnectionString.Parse(connection).Credentials;
        }
        private void ValidateRoundTrip(string connectionString)
        {
            var parsed = StorageConnectionString.Parse(connectionString);

            var reserialized = parsed.ToString(true);

            var reparsed = StorageConnectionString.Parse(reserialized);

            // make sure it round trips
            this.AccountsAreEqual(parsed, reparsed);
        }
예제 #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="QueueServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="connectionOptions">
        /// Optional connection options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        /// <remarks>
        /// The credentials on <paramref name="connectionString"/> will override those on <paramref name="connectionOptions"/>.
        /// </remarks>
        public QueueServiceClient(string connectionString, QueueConnectionOptions connectionOptions = default)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            // TODO: perform a copy of the options instead
            var connOptions = connectionOptions ?? new QueueConnectionOptions();

            connOptions.Credentials = conn.Credentials;

            this.Uri       = conn.QueueEndpoint;
            this._pipeline = connOptions.Build();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="QueueServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, see
        /// <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string">
        /// Configure Azure Storage connection strings</see>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public QueueServiceClient(string connectionString, QueueClientOptions options)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            _uri = conn.QueueEndpoint;
            options ??= new QueueClientOptions();
            _pipeline                   = options.Build(conn.Credentials);
            _version                    = options.Version;
            _clientDiagnostics          = new ClientDiagnostics(options);
            _clientSideEncryption       = QueueClientSideEncryptionOptions.CloneFrom(options._clientSideEncryptionOptions);
            _storageSharedKeyCredential = conn.Credentials as StorageSharedKeyCredential;
        }
        public void ExportKey()
        {
            var accountKeyString = "abc2564=";
            var accountString    = "BlobEndpoint=http://blobs/;AccountName=test;AccountKey=" + accountKeyString;
            var account          = StorageConnectionString.Parse(accountString);
            var accountAndKey    = (SharedKeyCredentials)account.Credentials;
            var key = accountAndKey.ExportBase64EncodedKey();

            Assert.AreEqual(accountKeyString, key);

            var keyBytes         = accountAndKey.AccountKeyValue;
            var expectedKeyBytes = Convert.FromBase64String(accountKeyString);

            TestHelper.AssertSequenceEqual(expectedKeyBytes, keyBytes);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="QueueServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, see
        /// <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string">
        /// Configure Azure Storage connection strings</see>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public QueueServiceClient(string connectionString, QueueClientOptions options)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            _uri = conn.QueueEndpoint;
            options ??= new QueueClientOptions();
            _clientConfiguration = new QueueClientConfiguration(
                pipeline: options.Build(conn.Credentials),
                sharedKeyCredential: conn.Credentials as StorageSharedKeyCredential,
                clientDiagnostics: new StorageClientDiagnostics(options),
                version: options.Version,
                clientSideEncryption: QueueClientSideEncryptionOptions.CloneFrom(options._clientSideEncryptionOptions),
                messageEncoding: options.MessageEncoding,
                queueMessageDecodingFailedHandlers: options.GetMessageDecodingFailedHandlers());

            _serviceRestClient = BuildServiceRestClient();
        }
예제 #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="QueueClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="queueName">
        /// The name of the queue in the storage account to reference.
        /// </param>
        /// <param name="connectionOptions">
        /// Optional connection options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        /// <remarks>
        /// The credentials on <paramref name="connectionString"/> will override those on <paramref name="connectionOptions"/>.
        /// </remarks>
        public QueueClient(string connectionString, string queueName, QueueConnectionOptions connectionOptions = default)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            var builder =
                new QueueUriBuilder(conn.QueueEndpoint)
            {
                QueueName = queueName
            };

            // TODO: perform a copy of the options instead
            var connOptions = connectionOptions ?? new QueueConnectionOptions();

            connOptions.Credentials = conn.Credentials;

            this.Uri       = builder.ToUri();
            this._pipeline = connOptions.Build();
        }
        public void EndpointSuffixWithBlob()
        {
            const string TestEndpointSuffix    = "fake.endpoint.suffix";
            const string AlternateBlobEndpoint = "http://blob.other.endpoint/";

            var testAccount =
                StorageConnectionString.Parse(
                    global::System.String.Format(
                        "DefaultEndpointsProtocol=http;AccountName={0};AccountKey={1};EndpointSuffix={2};BlobEndpoint={3}",
                        TestConfigurations.DefaultTargetTenant.AccountName,
                        TestConfigurations.DefaultTargetTenant.AccountKey,
                        TestEndpointSuffix,
                        AlternateBlobEndpoint));

            var conn = StorageConnectionString.Parse(testAccount.ToString(true));

            // make sure it round trips
            this.AccountsAreEqual(testAccount, conn);
        }
예제 #20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DirectoryClient"/> class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string"/>.
        /// </param>
        /// <param name="shareName">
        /// The name of the share in the storage account to reference.
        /// </param>
        /// <param name="directoryPath">
        /// The path of the directory in the storage account to reference.
        /// </param>
        /// <param name="connectionOptions">
        /// Optional <see cref="FileConnectionOptions"/> that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        /// <remarks>
        /// The credentials on <paramref name="connectionString"/> will override those on <paramref name="connectionOptions"/>.
        /// </remarks>
        public DirectoryClient(string connectionString, string shareName, string directoryPath, FileConnectionOptions connectionOptions = default)
        {
            var conn = StorageConnectionString.Parse(connectionString);

            var builder =
                new FileUriBuilder(conn.FileEndpoint)
            {
                ShareName           = shareName,
                DirectoryOrFilePath = directoryPath
            };

            // TODO: perform a copy of the options instead
            var connOptions = connectionOptions ?? new FileConnectionOptions();

            connOptions.Credentials = conn.Credentials;

            this.Uri       = builder.ToUri();
            this._pipeline = connOptions.Build();
        }
예제 #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DataLakeServiceClient"/>
        /// class.
        /// </summary>
        /// <param name="connectionString">
        /// A connection string includes the authentication information
        /// required for your application to access data in an Azure Storage
        /// account at runtime.
        ///
        /// For more information, <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string">Configure Azure Storage connection strings</see>.
        /// </param>
        /// <param name="options">
        /// Optional client options that define the transport pipeline
        /// policies for authentication, retries, etc., that are applied to
        /// every request.
        /// </param>
        public DataLakeServiceClient(string connectionString, DataLakeClientOptions options)
        {
            StorageConnectionString    conn = StorageConnectionString.Parse(connectionString);
            StorageSharedKeyCredential sharedKeyCredential = conn.Credentials as StorageSharedKeyCredential;

            options ??= new DataLakeClientOptions();
            HttpPipelinePolicy authPolicy = sharedKeyCredential.AsPolicy();

            _pipeline                   = options.Build(authPolicy);
            _uri                        = conn.BlobEndpoint;
            _blobUri                    = new DataLakeUriBuilder(_uri).ToBlobUri();
            _version                    = options.Version;
            _clientDiagnostics          = new ClientDiagnostics(options);
            _storageSharedKeyCredential = sharedKeyCredential;
            _blobServiceClient          = BlobServiceClientInternals.Create(
                _blobUri,
                _pipeline,
                authPolicy,
                Version.AsBlobsVersion(),
                _clientDiagnostics);
        }
        public void StorageCredentialsEmptyKeyValue()
        {
            var accountName = TestConfigurations.DefaultTargetTenant.AccountName;

            _ = TestConfigurations.DefaultTargetTenant.AccountKey;
            var emptyKeyValueAsString    = String.Empty;
            var emptyKeyConnectionString = String.Format(CultureInfo.InvariantCulture, "DefaultEndpointsProtocol=https;AccountName={0};AccountKey=", accountName);

            var credentials1 = new SharedKeyCredentials(accountName, emptyKeyValueAsString);

            var conn1 = new StorageConnectionString(credentials1, true);

            Assert.AreEqual(emptyKeyConnectionString, conn1.ToString(true));
            Assert.IsNotNull(conn1.Credentials);
            Assert.IsInstanceOf(typeof(SharedKeyCredentials), conn1.Credentials);
            Assert.AreEqual(accountName, ((SharedKeyCredentials)conn1.Credentials).AccountName);
            Assert.AreEqual(emptyKeyValueAsString, ((SharedKeyCredentials)conn1.Credentials).ExportBase64EncodedKey());

            var account2 = StorageConnectionString.Parse(emptyKeyConnectionString);

            Assert.AreEqual(emptyKeyConnectionString, account2.ToString(true));
            Assert.IsNotNull(account2.Credentials);
            Assert.IsInstanceOf(typeof(SharedKeyCredentials), account2.Credentials);
            Assert.AreEqual(accountName, ((SharedKeyCredentials)account2.Credentials).AccountName);
            Assert.AreEqual(emptyKeyValueAsString, ((SharedKeyCredentials)account2.Credentials).ExportBase64EncodedKey());

            var isValidAccount3 = StorageConnectionString.TryParse(emptyKeyConnectionString, out var account3);

            Assert.IsTrue(isValidAccount3);
            Assert.IsNotNull(account3);
            Assert.AreEqual(emptyKeyConnectionString, account3.ToString(true));
            Assert.IsNotNull(account3.Credentials);
            Assert.IsInstanceOf(typeof(SharedKeyCredentials), account3.Credentials);
            Assert.AreEqual(accountName, ((SharedKeyCredentials)account3.Credentials).AccountName);
            Assert.AreEqual(emptyKeyValueAsString, ((SharedKeyCredentials)account3.Credentials).ExportBase64EncodedKey());
        }
        public void ValidateExpectedExceptions()
        {
            var endpointCombinations = new[]
            {
                new[] { "BlobEndpoint={3}", "BlobSecondaryEndpoint={4}", "BlobEndpoint={3};BlobSecondaryEndpoint={4}" },
                new[] { "QueueEndpoint={3}", "QueueSecondaryEndpoint={4}", "QueueEndpoint={3};QueueSecondaryEndpoint={4}" },
                new[] { "TableEndpoint={3}", "TableSecondaryEndpoint={4}", "TableEndpoint={3};TableSecondaryEndpoint={4}" },
                new[] { "FileEndpoint={3}", "FileSecondaryEndpoint={4}", "FileEndpoint={3};FileSecondaryEndpoint={4}" }
            };

            var accountKeyParams = new[]
            {
                TestConfigurations.DefaultTargetTenant.AccountName,
                TestConfigurations.DefaultTargetTenant.AccountKey,
                "fake.endpoint.suffix",
                "https://primary.endpoint/",
                "https://secondary.endpoint/"
            };

            var accountSasParams = new[]
            {
                TestConfigurations.DefaultTargetTenant.AccountName,
                "sasTest",
                "fake.endpoint.suffix",
                "https://primary.endpoint/",
                "https://secondary.endpoint/"
            };

            foreach (var endpointCombination in endpointCombinations)
            {
                // account key

                var accountStringKeyPrimary =
                    String.Format(
                        "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2};" + endpointCombination[0],
                        accountKeyParams
                        );

                var accountStringKeySecondary =
                    String.Format(
                        "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2};" + endpointCombination[1],
                        accountKeyParams
                        );


                var accountStringKeyPrimarySecondary =
                    String.Format(
                        "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2};" + endpointCombination[2],
                        accountKeyParams
                        );


                StorageConnectionString.Parse(accountStringKeyPrimary); // no exception expected

                TestHelper.AssertExpectedException(
                    () => StorageConnectionString.Parse(accountStringKeySecondary),
                    new FormatException("No valid combination of account information found.")
                    );

                StorageConnectionString.Parse(accountStringKeyPrimarySecondary); // no exception expected

                // account key, no default protocol

                var accountStringKeyNoDefaultProtocolPrimary =
                    String.Format(
                        "AccountName={0};AccountKey={1};EndpointSuffix={2};" + endpointCombination[0],
                        accountKeyParams
                        );

                var accountStringKeyNoDefaultProtocolSecondary =
                    String.Format(
                        "AccountName={0};AccountKey={1};EndpointSuffix={2};" + endpointCombination[1],
                        accountKeyParams
                        );


                var accountStringKeyNoDefaultProtocolPrimarySecondary =
                    String.Format(
                        "AccountName={0};AccountKey={1};EndpointSuffix={2};" + endpointCombination[2],
                        accountKeyParams
                        );


                StorageConnectionString.Parse(accountStringKeyNoDefaultProtocolPrimary); // no exception expected

                TestHelper.AssertExpectedException(
                    () => StorageConnectionString.Parse(accountStringKeyNoDefaultProtocolSecondary),
                    new FormatException("No valid combination of account information found.")
                    );

                StorageConnectionString.Parse(accountStringKeyNoDefaultProtocolPrimarySecondary); // no exception expected

                // SAS

                var accountStringSasPrimary =
                    String.Format(
                        "DefaultEndpointsProtocol=https;AccountName={0};SharedAccessSignature={1};EndpointSuffix={2};" + endpointCombination[0],
                        accountSasParams
                        );

                var accountStringSasSecondary =
                    String.Format(
                        "DefaultEndpointsProtocol=https;AccountName={0};SharedAccessSignature={1};EndpointSuffix={2};" + endpointCombination[1],
                        accountSasParams
                        );

                var accountStringSasPrimarySecondary =
                    String.Format(
                        "DefaultEndpointsProtocol=https;AccountName={0};SharedAccessSignature={1};EndpointSuffix={2};" + endpointCombination[2],
                        accountSasParams
                        );

                StorageConnectionString.Parse(accountStringSasPrimary); // no exception expected

                TestHelper.AssertExpectedException(
                    () => StorageConnectionString.Parse(accountStringSasSecondary),
                    new FormatException("No valid combination of account information found.")
                    );

                StorageConnectionString.Parse(accountStringSasPrimarySecondary); // no exception expected

                // SAS, no default protocol

                var accountStringSasNoDefaultProtocolPrimary =
                    String.Format(
                        "AccountName={0};SharedAccessSignature={1};EndpointSuffix={2};" + endpointCombination[0],
                        accountSasParams
                        );

                var accountStringSasNoDefaultProtocolSecondary =
                    String.Format(
                        "AccountName={0};SharedAccessSignature={1};EndpointSuffix={2};" + endpointCombination[1],
                        accountSasParams
                        );

                var accountStringSasNoDefaultProtocolPrimarySecondary =
                    String.Format(
                        "AccountName={0};SharedAccessSignature={1};EndpointSuffix={2};" + endpointCombination[2],
                        accountSasParams
                        );

                StorageConnectionString.Parse(accountStringSasNoDefaultProtocolPrimary); // no exception expected

                TestHelper.AssertExpectedException(
                    () => StorageConnectionString.Parse(accountStringSasNoDefaultProtocolSecondary),
                    new FormatException("No valid combination of account information found.")
                    );

                StorageConnectionString.Parse(accountStringSasNoDefaultProtocolPrimarySecondary); // no exception expected

                // SAS without AccountName

                var accountStringSasNoNameNoEndpoint =
                    String.Format(
                        "SharedAccessSignature={1}",
                        accountSasParams
                        );

                var accountStringSasNoNamePrimary =
                    String.Format(
                        "SharedAccessSignature={1};" + endpointCombination[0],
                        accountSasParams
                        );

                var accountStringSasNoNameSecondary =
                    String.Format(
                        "SharedAccessSignature={1};" + endpointCombination[1],
                        accountSasParams
                        );

                var accountStringSasNoNamePrimarySecondary =
                    String.Format(
                        "SharedAccessSignature={1};" + endpointCombination[2],
                        accountSasParams
                        );

                TestHelper.AssertExpectedException(
                    () => StorageConnectionString.Parse(accountStringSasNoNameNoEndpoint),
                    new FormatException("No valid combination of account information found.")
                    );

                StorageConnectionString.Parse(accountStringSasNoNamePrimary); // no exception expected

                TestHelper.AssertExpectedException(
                    () => StorageConnectionString.Parse(accountStringSasNoNameSecondary),
                    new FormatException("No valid combination of account information found.")
                    );

                StorageConnectionString.Parse(accountStringSasNoNamePrimarySecondary); // no exception expected
            }
        }
        public void DefaultCloudRoundtrip()
        {
            var accountString = "DefaultEndpointsProtocol=http;AccountName=test;AccountKey=abc=";

            Assert.AreEqual(accountString, StorageConnectionString.Parse(accountString).ToString(true));
        }
        public void DevStoreProxyRoundtrip()
        {
            var accountString = "UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://ipv4.fiddler/";

            Assert.AreEqual(accountString, StorageConnectionString.Parse(accountString).ToString(true));
        }
        public void DevStoreRoundtrip()
        {
            var accountString = "UseDevelopmentStorage=true";

            Assert.AreEqual(accountString, StorageConnectionString.Parse(accountString).ToString(true));
        }