< Summary

Class:Azure.Storage.Files.DataLake.DataLakeUriBuilder
Assembly:Azure.Storage.Files.DataLake
File(s):C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Files.DataLake\src\DataLakeUriBuilder.cs
Covered lines:107
Uncovered lines:9
Coverable lines:116
Total lines:399
Line coverage:92.2% (107 of 116)
Covered branches:46
Total branches:52
Branch coverage:88.4% (46 of 52)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
get_Scheme()-100%100%
set_Scheme(...)-100%100%
get_Host()-100%100%
set_Host(...)-100%100%
get_Port()-100%100%
set_Port(...)-100%100%
get_AccountName()-100%100%
set_AccountName(...)-100%100%
get_FileSystemName()-100%100%
set_FileSystemName(...)-100%100%
get_DirectoryOrFilePath()-100%100%
set_DirectoryOrFilePath(...)-100%100%
get_Snapshot()-100%100%
set_Snapshot(...)-100%100%
get_Sas()-100%100%
set_Sas(...)-100%100%
get_LastDirectoryOrFileName()-100%100%
get_Query()-100%100%
set_Query(...)-100%100%
.ctor(...)-89.74%88.89%
ToUri()-100%100%
ToBlobUri()-100%100%
ToDfsUri()-100%100%
ToString()-0%100%
ResetUri()-100%100%
BuildUri()-85.19%81.82%

File(s)

C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Files.DataLake\src\DataLakeUriBuilder.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Globalization;
 6using System.Linq;
 7using System.Net;
 8using System.Text;
 9using Azure.Core;
 10using Azure.Storage.Sas;
 11using Azure.Storage.Shared;
 12
 13namespace Azure.Storage.Files.DataLake
 14{
 15    /// <summary>
 16    /// The <see cref="DataLakeUriBuilder"/> class provides a convenient way to
 17    /// modify the contents of a <see cref="System.Uri"/> instance to point to
 18    /// different Azure Data Lake resources like an file system, directory, or file.
 19    /// </summary>
 20    public class DataLakeUriBuilder
 21    {
 22        /// <summary>
 23        /// The Uri instance constructed by this builder.  It will be reset to
 24        /// null when changes are made and reconstructed when <see cref="System.Uri"/>
 25        /// is accessed.
 26        /// </summary>
 27        private Uri _uri;
 28
 29        /// <summary>
 30        /// Whether the Uri is an IP Uri as determined by
 31        /// <see cref="UriExtensions.IsHostIPEndPointStyle(Uri)"/>.
 32        /// </summary>
 33        private readonly bool _isIPStyleUri;
 34
 35        /// <summary>
 36        /// Gets or sets the scheme name of the URI.
 37        /// Example: "https"
 38        /// </summary>
 39        public string Scheme
 40        {
 1817441            get => _scheme;
 3588642            set { ResetUri(); _scheme = value; }
 43        }
 44        private string _scheme;
 45
 46        /// <summary>
 47        /// Gets or sets the Domain Name System (DNS) host name or IP address
 48        /// of a server.
 49        ///
 50        /// Example: "account.file.core.windows.net"
 51        /// </summary>
 52        public string Host
 53        {
 4378854            get => _host;
 5915455            set { ResetUri(); _host = value; }
 56        }
 57        private string _host;
 58
 59        /// <summary>
 60        /// Gets or sets the port number of the URI.
 61        /// </summary>
 62        public int Port
 63        {
 1817464            get => _port;
 3588665            set { ResetUri(); _port = value; }
 66        }
 67        private int _port;
 68
 69        /// <summary>
 70        /// Gets or sets the Azure Storage account name.
 71        /// </summary>
 72        public string AccountName
 73        {
 876474            get => _accountName;
 7177275            set { ResetUri(); _accountName = value; }
 76        }
 77        private string _accountName;
 78
 79        /// <summary>
 80        /// Gets or sets the name of a file storage share.  The value defaults
 81        /// to <see cref="string.Empty"/> if not present in the
 82        /// <see cref="System.Uri"/>.
 83        ///
 84        /// </summary>
 85        public string FileSystemName
 86        {
 3462287            get => _fileSystemName;
 7238488            set { ResetUri(); _fileSystemName = value; }
 89        }
 90        private string _fileSystemName;
 91
 92        /// <summary>
 93        /// Gets or sets the path of the directory or file.  The value defaults
 94        /// to <see cref="string.Empty"/> if not present in the
 95        /// <see cref="System.Uri"/>.
 96        /// Example: "mydirectory/myfile"
 97        /// </summary>
 98        public string DirectoryOrFilePath
 99        {
 35352100            get => _directoryOrFilePath;
 101            set
 102            {
 18384103                ResetUri();
 18384104                if (value == "/")
 105                {
 24106                    _directoryOrFilePath = value;
 107                }
 108                else
 109                {
 18360110                    _directoryOrFilePath = value.TrimEnd('/');
 111                }
 18360112            }
 113        }
 114
 115        private string _directoryOrFilePath;
 116
 117        /// <summary>
 118        /// Gets or sets the name of a file snapshot.  The value defaults to
 119        /// <see cref="string.Empty"/> if not present in the <see cref="System.Uri"/>.
 120        /// </summary>
 121        public string Snapshot
 122        {
 18174123            get => _snapshot;
 35886124            set { ResetUri(); _snapshot = value; }
 125        }
 126        private string _snapshot;
 127
 128        /// <summary>
 129        /// Gets or sets the Shared Access Signature query parameters, or null
 130        /// if not present in the <see cref="System.Uri"/>.
 131        /// </summary>
 132        public DataLakeSasQueryParameters Sas
 133        {
 18402134            get => _sas;
 37692135            set { ResetUri(); _sas = value; }
 136        }
 137        private DataLakeSasQueryParameters _sas;
 138
 139        /// <summary>
 140        /// Get the last directory or file name from the <see cref="DirectoryOrFilePath"/>, or null if
 141        /// not present in the <see cref="Uri"/>.
 142        /// </summary>
 143        internal string LastDirectoryOrFileName =>
 896144            DirectoryOrFilePath.TrimEnd('/').Split('/').LastOrDefault();
 145
 146        /// <summary>
 147        /// Gets or sets any query information included in the URI that's not
 148        /// relevant to addressing Azure storage resources.
 149        /// </summary>
 150        public string Query
 151        {
 18170152            get => _query;
 36510153            set { ResetUri(); _query = value; }
 154        }
 155        private string _query;
 156
 157        /// <summary>
 158        /// Initializes a new instance of the <see cref="DataLakeUriBuilder"/>
 159        /// class with the specified <see cref="System.Uri"/>.
 160        /// </summary>
 161        /// <param name="uri">
 162        /// The <see cref="System.Uri"/> to a storage resource.
 163        /// </param>
 11962164        public DataLakeUriBuilder(Uri uri)
 165        {
 11962166            Scheme = uri.Scheme;
 11962167            Host = uri.Host;
 11962168            Port = uri.Port;
 11962169            AccountName = "";
 170
 11962171            FileSystemName = "";
 11962172            DirectoryOrFilePath = "";
 173
 11962174            Snapshot = "";
 11962175            Sas = null;
 176
 177            // Find the share & directory/file path (if any)
 11962178            if (!string.IsNullOrEmpty(uri.AbsolutePath))
 179            {
 11962180                var path = uri.GetPath();
 181
 11962182                var startIndex = 0;
 183
 11962184                if (uri.IsHostIPEndPointStyle())
 185                {
 8186                    _isIPStyleUri = true;
 8187                    var accountEndIndex = path.IndexOf("/", StringComparison.InvariantCulture);
 188
 189                    // Slash not found; path has account name & no share name
 8190                    if (accountEndIndex == -1)
 191                    {
 8192                        AccountName = path;
 8193                        startIndex = path.Length;
 194                    }
 195                    else
 196                    {
 0197                        AccountName = path.Substring(0, accountEndIndex);
 0198                        startIndex = accountEndIndex + 1;
 199                    }
 200                }
 201                else
 202                {
 203                    // DataLake Uris have two allowed subdomains
 11954204                    AccountName = uri.GetAccountNameFromDomain(Constants.DataLake.BlobUriSuffix) ??
 11954205                        uri.GetAccountNameFromDomain(Constants.DataLake.DfsUriSuffix) ??
 11954206                        string.Empty;
 207                }
 208
 209                // Find the next slash (if it exists)
 11962210                var shareEndIndex = path.IndexOf("/", startIndex, StringComparison.InvariantCulture);
 11962211                if (shareEndIndex == -1)
 212                {
 213                    // Slash not found; path has file system & no directory/file path
 9586214                    FileSystemName = path.Substring(startIndex);
 215                }
 216                else
 217                {
 218                    // The file system name is the part between the slashes
 2376219                    FileSystemName = path.Substring(startIndex, shareEndIndex - startIndex);
 2376220                    string directoryOrFilePath = path.Substring(shareEndIndex + 1);
 221
 222                    // The directory/file path name is after the share slash
 2376223                    if (directoryOrFilePath.Length == 0)
 224                    {
 24225                        DirectoryOrFilePath = "/";
 226                    }
 227                    else
 228                    {
 2352229                        DirectoryOrFilePath = directoryOrFilePath.UnescapePath();
 230                    }
 231
 232                }
 233            }
 234
 235            // Convert the query parameters to a case-sensitive map & trim whitespace
 236
 11962237            var paramsMap = new UriQueryParamsCollection(uri.Query);
 238
 11962239            if (paramsMap.TryGetValue(Constants.SnapshotParameterName, out var snapshotTime))
 240            {
 0241                Snapshot = snapshotTime;
 242
 243                // If we recognized the query parameter, remove it from the map
 0244                paramsMap.Remove(Constants.SnapshotParameterName);
 245            }
 246
 11962247            if (paramsMap.ContainsKey(Constants.Sas.Parameters.Version))
 248            {
 386249                Sas = new DataLakeSasQueryParameters(paramsMap);
 250            }
 251
 11962252            Query = paramsMap.ToString();
 11962253        }
 254
 255        /// <summary>
 256        /// Returns the <see cref="System.Uri"/> constructed from the
 257        /// <see cref="DataLakeUriBuilder"/>'s fields. The <see cref="Uri.Query"/>
 258        /// property contains the SAS and additional query parameters.
 259        /// </summary>
 260        public Uri ToUri()
 261        {
 22032262            if (_uri == null)
 263            {
 18166264                _uri = BuildUri().ToUri();
 265            }
 22032266            return _uri;
 267        }
 268
 269        /// <summary>
 270        /// Gets the blob Uri.
 271        /// </summary>
 272        internal Uri ToBlobUri()
 273        {
 10390274            if (!_isIPStyleUri)
 275            {
 10386276                string account = UriExtensions.GetAccountNameFromDomain(Host, Constants.DataLake.DfsUriSuffix);
 277
 10386278                if (account != null)
 279                {
 332280                    StringBuilder stringBuilder = new StringBuilder(Host);
 281
 282                    // Replace "dfs" with "blob"
 332283                    stringBuilder.Replace(
 332284                        Constants.DataLake.DfsUriSuffix,
 332285                        Constants.DataLake.BlobUriSuffix,
 332286                        AccountName.Length + 1,
 332287                        3);
 332288                    Host = stringBuilder.ToString();
 289                }
 290            }
 291
 10390292            return ToUri();
 293        }
 294
 295        /// <summary>
 296        /// Gets the dfs Uri.
 297        /// </summary>
 298        internal Uri ToDfsUri()
 299        {
 7476300            if (!_isIPStyleUri)
 301            {
 7472302                string account = UriExtensions.GetAccountNameFromDomain(Host, Constants.DataLake.BlobUriSuffix);
 303
 7472304                if (account != null)
 305                {
 7424306                    StringBuilder stringBuilder = new StringBuilder(Host);
 307
 308                    // Replace "blob" with "dfs"
 7424309                    stringBuilder.Replace(
 7424310                        Constants.DataLake.BlobUriSuffix,
 7424311                        Constants.DataLake.DfsUriSuffix,
 7424312                        AccountName.Length + 1,
 7424313                        4);
 7424314                    Host = stringBuilder.ToString();
 315                }
 316
 317            }
 318
 7476319            return ToUri();
 320        }
 321
 322        /// <summary>
 323        /// Returns the display string for the specified
 324        /// <see cref="DataLakeUriBuilder"/> instance.
 325        /// </summary>
 326        /// <returns>
 327        /// The display string for the specified <see cref="DataLakeUriBuilder"/>
 328        /// instance.
 329        /// </returns>
 330        public override string ToString() =>
 0331            BuildUri().ToString();
 332
 333        /// <summary>
 334        /// Reset our cached URI.
 335        /// </summary>
 336        private void ResetUri() =>
 146774337            _uri = null;
 338
 339        /// <summary>
 340        /// Construct a <see cref="RequestUriBuilder"/> representing the
 341        /// <see cref="DataLakeUriBuilder"/>'s fields. The <see cref="Uri.Query"/>
 342        /// property contains the SAS, snapshot, and additional query parameters.
 343        /// </summary>
 344        /// <returns>The constructed <see cref="RequestUriBuilder"/>.</returns>
 345        private RequestUriBuilder BuildUri()
 346        {
 347            // Concatenate account, share & directory/file path (if they exist)
 18166348            var path = new StringBuilder("");
 349            // only append the account name to the path for Ip style Uri.
 350            // regular style Uri will already have account name in domain
 18166351            if (_isIPStyleUri && !string.IsNullOrWhiteSpace(AccountName))
 352            {
 8353                path.Append("/").Append(AccountName);
 354            }
 18166355            if (!string.IsNullOrWhiteSpace(FileSystemName))
 356            {
 15104357                path.Append("/").Append(FileSystemName);
 15104358                if (!string.IsNullOrWhiteSpace(DirectoryOrFilePath))
 359                {
 9144360                    if (DirectoryOrFilePath == "/")
 361                    {
 36362                        path.Append(_directoryOrFilePath);
 363                    }
 364                    else
 365                    {
 366                        // Encode path.
 9108367                        path.Append("/").Append(DirectoryOrFilePath.EscapePath());
 368                    }
 369                }
 370            }
 371
 372            // Concatenate query parameters
 18166373            var query = new StringBuilder(Query);
 18166374            if (!string.IsNullOrWhiteSpace(Snapshot))
 375            {
 0376                if (query.Length > 0)
 0377                { query.Append("&"); }
 0378                query.Append(Constants.SnapshotParameterName).Append("=").Append(Snapshot);
 379            }
 18166380            var sas = Sas?.ToString();
 18166381            if (!string.IsNullOrWhiteSpace(sas))
 382            {
 548383                if (query.Length > 0)
 0384                { query.Append("&"); }
 548385                query.Append(sas);
 386            }
 387
 388            // Use RequestUriBuilder, which has slightly nicer formatting
 18166389            return new RequestUriBuilder
 18166390            {
 18166391                Scheme = Scheme,
 18166392                Host = Host,
 18166393                Port = Port,
 18166394                Path = path.ToString(),
 18166395                Query = query.Length > 0 ? "?" + query.ToString() : null
 18166396            };
 397        }
 398    }
 399}