diff --git a/eng/CodeAnalysis.ruleset b/eng/CodeAnalysis.ruleset index fb46145c3031..2ebb3f39641b 100644 --- a/eng/CodeAnalysis.ruleset +++ b/eng/CodeAnalysis.ruleset @@ -190,7 +190,7 @@ - + diff --git a/sdk/core/Azure.Core/src/AccessToken.cs b/sdk/core/Azure.Core/src/AccessToken.cs index c1a78589186f..0f245a3a4cf0 100644 --- a/sdk/core/Azure.Core/src/AccessToken.cs +++ b/sdk/core/Azure.Core/src/AccessToken.cs @@ -5,18 +5,33 @@ namespace Azure.Core { + /// + /// Represents an Azure service bearer access token with expiry information. + /// public struct AccessToken { + /// + /// Creates a new instance of using the provided and . + /// + /// The bearer access token value. + /// The bearer access token expiry date. public AccessToken(string accessToken, DateTimeOffset expiresOn) { Token = accessToken; ExpiresOn = expiresOn; } - public string Token { get; private set; } + /// + /// Get the access token value. + /// + public string Token { get; } - public DateTimeOffset ExpiresOn { get; private set; } + /// + /// Gets the time when the provided token expires. + /// + public DateTimeOffset ExpiresOn { get; } + /// public override bool Equals(object? obj) { if (obj is AccessToken accessToken) @@ -27,6 +42,7 @@ public override bool Equals(object? obj) return false; } + /// public override int GetHashCode() { return Token.GetHashCode() ^ ExpiresOn.GetHashCode(); diff --git a/sdk/core/Azure.Core/src/AsyncPageable.cs b/sdk/core/Azure.Core/src/AsyncPageable.cs index ecafa3f69a26..dcd861fea0fa 100644 --- a/sdk/core/Azure.Core/src/AsyncPageable.cs +++ b/sdk/core/Azure.Core/src/AsyncPageable.cs @@ -41,7 +41,7 @@ protected AsyncPageable(CancellationToken cancellationToken) => /// /// Enumerate the values a at a time. This may - /// make mutliple service requests. + /// make multiple service requests. /// /// /// A continuation token indicating where to resume paging or null to @@ -60,7 +60,7 @@ public abstract IAsyncEnumerable> AsPages( /// /// Enumerate the values in the collection asynchronously. This may - /// make mutliple service requests. + /// make multiple service requests. /// /// /// The used for requests made while diff --git a/sdk/core/Azure.Core/src/AzureExtensions.cs b/sdk/core/Azure.Core/src/AzureExtensions.cs index 8f2b4b6e2593..69c432aeb3f3 100644 --- a/sdk/core/Azure.Core/src/AzureExtensions.cs +++ b/sdk/core/Azure.Core/src/AzureExtensions.cs @@ -7,6 +7,9 @@ namespace Azure { + /// + /// Extension for various types. + /// public static class AzureExtensions { /// diff --git a/sdk/core/Azure.Core/src/ClientOptions.cs b/sdk/core/Azure.Core/src/ClientOptions.cs index ea16a57a6f52..f2994fee930c 100644 --- a/sdk/core/Azure.Core/src/ClientOptions.cs +++ b/sdk/core/Azure.Core/src/ClientOptions.cs @@ -8,26 +8,48 @@ namespace Azure.Core { + /// + /// Base type for all client option types, exposes various common client options like , , . + /// public abstract class ClientOptions { private HttpPipelineTransport _transport = HttpClientTransport.Shared; + /// + /// Creates a new instance of . + /// protected ClientOptions() { Retry = new RetryOptions(); Diagnostics = new DiagnosticsOptions(); } + /// + /// The to be used for this client. Defaults to an instance of . + /// public HttpPipelineTransport Transport { get => _transport; set => _transport = value ?? throw new ArgumentNullException(nameof(value)); } + /// + /// Gets the client diagnostic options. + /// public DiagnosticsOptions Diagnostics { get; } + /// + /// Gets the client retry options. + /// public RetryOptions Retry { get; } + /// + /// Adds an policy into the client pipeline. The position of policy in the pipeline is controlled by parameter. + /// If you want the policy to execute once per client request use otherwise use + /// to run the policy for every retry. Note that the same instance of would be added to all pipelines of client constructed using this object. + /// + /// The instance to be added to the pipeline. + /// The position of policy in the pipeline. public void AddPolicy(HttpPipelinePolicy policy, HttpPipelinePosition position) { switch (position) @@ -47,15 +69,16 @@ public void AddPolicy(HttpPipelinePolicy policy, HttpPipelinePosition position) internal IList PerRetryPolicies { get; } = new List(); - #region nobody wants to see these + /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object? obj) => base.Equals(obj); + /// [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() => base.GetHashCode(); + /// [EditorBrowsable(EditorBrowsableState.Never)] public override string ToString() => base.ToString(); - #endregion } } diff --git a/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKey.cs b/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKey.cs index abb2e5a329b7..0e84fd3bc95d 100644 --- a/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKey.cs +++ b/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKey.cs @@ -8,7 +8,7 @@ namespace Azure.Core.Cryptography { /// - /// A key which is used to encrypt, or wrap, another key + /// A key which is used to encrypt, or wrap, another key. /// public interface IKeyEncryptionKey { @@ -18,39 +18,39 @@ public interface IKeyEncryptionKey string KeyId { get; } /// - /// Encrypts the specified key using the specified algorithm + /// Encrypts the specified key using the specified algorithm. /// - /// The key wrap algorithm used to encrypt the specified key - /// The key to be encrypted + /// The key wrap algorithm used to encrypt the specified key. + /// The key to be encrypted. /// A controlling the request lifetime. - /// The encrypted key bytes + /// The encrypted key bytes. byte[] WrapKey(string algorithm, ReadOnlyMemory key, CancellationToken cancellationToken = default); /// - /// Encrypts the specified key using the specified algorithm + /// Encrypts the specified key using the specified algorithm. /// - /// The key wrap algorithm used to encrypt the specified key - /// The key to be encrypted + /// The key wrap algorithm used to encrypt the specified key. + /// The key to be encrypted. /// A controlling the request lifetime. - /// The encrypted key bytes + /// The encrypted key bytes. Task WrapKeyAsync(string algorithm, ReadOnlyMemory key, CancellationToken cancellationToken = default); /// - /// Decrypts the specified encrpted key using the specified algorithm + /// Decrypts the specified encrypted key using the specified algorithm. /// - /// The key wrap algorithm which was used to encrypt the specified encrypted key - /// The encrypted key to be decrypted + /// The key wrap algorithm which was used to encrypt the specified encrypted key. + /// The encrypted key to be decrypted. /// A controlling the request lifetime. - /// The decrpted key bytes + /// The decrypted key bytes. byte[] UnwrapKey(string algorithm, ReadOnlyMemory encryptedKey, CancellationToken cancellationToken = default); /// - /// Decrypts the specified encrpted key using the specified algorithm + /// Decrypts the specified encrypted key using the specified algorithm. /// - /// The key wrap algorithm which was used to encrypt the specified encrypted key - /// The encrypted key to be decrypted + /// The key wrap algorithm which was used to encrypt the specified encrypted key. + /// The encrypted key to be decrypted. /// A controlling the request lifetime. - /// The decrpted key bytes + /// The decrypted key bytes. Task UnwrapKeyAsync(string algorithm, ReadOnlyMemory encryptedKey, CancellationToken cancellationToken = default); } } diff --git a/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKeyResolver.cs b/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKeyResolver.cs index 211ee7986882..07d483686017 100644 --- a/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKeyResolver.cs +++ b/sdk/core/Azure.Core/src/Cryptography/IKeyEncryptionKeyResolver.cs @@ -12,19 +12,19 @@ namespace Azure.Core.Cryptography public interface IKeyEncryptionKeyResolver { /// - /// Retrieves the key encryption key corresponding to the specified keyId + /// Retrieves the key encryption key corresponding to the specified keyId. /// - /// The key idenitifier of the key encryption key to retrieve + /// The key identifier of the key encryption key to retrieve. /// A controlling the request lifetime. - /// The key encryption key corresponding to the specified keyId + /// The key encryption key corresponding to the specified keyId. IKeyEncryptionKey Resolve(string keyId, CancellationToken cancellationToken = default); /// - /// Retrieves the key encryption key corresponding to the specified keyId + /// Retrieves the key encryption key corresponding to the specified keyId. /// - /// The key idenitifier of the key encryption key to retrieve + /// The key identifier of the key encryption key to retrieve. /// A controlling the request lifetime. - /// The key encryption key corresponding to the specified keyId + /// The key encryption key corresponding to the specified keyId. Task ResolveAsync(string keyId, CancellationToken cancellationToken = default); } } diff --git a/sdk/core/Azure.Core/src/Diagnostics/AzureEventSourceListener.cs b/sdk/core/Azure.Core/src/Diagnostics/AzureEventSourceListener.cs index 13aacb2d3f22..bbfd77a574e1 100644 --- a/sdk/core/Azure.Core/src/Diagnostics/AzureEventSourceListener.cs +++ b/sdk/core/Azure.Core/src/Diagnostics/AzureEventSourceListener.cs @@ -11,11 +11,17 @@ namespace Azure.Core.Diagnostics { /// - /// Implementation of that listens to events produces by Azure SDK Client libraries + /// Implementation of that listens to events produces by Azure SDK Client libraries. /// public class AzureEventSourceListener: EventListener { + /// + /// The trait name that has to be present on all event sources collected by this listener. + /// public const string TraitName = "AzureEventSource"; + /// + /// The trait value that has to be present on all event sources collected by this listener. + /// public const string TraitValue = "true"; private readonly List _eventSources = new List(); @@ -42,6 +48,7 @@ public AzureEventSourceListener(Action log, Event _eventSources.Clear(); } + /// protected sealed override void OnEventSourceCreated(EventSource eventSource) { base.OnEventSourceCreated(eventSource); @@ -57,13 +64,14 @@ protected sealed override void OnEventSourceCreated(EventSource eventSource) } } + /// protected sealed override void OnEventWritten(EventWrittenEventArgs eventData) { _log(eventData, EventSourceEventFormatting.Format(eventData)); } /// - /// Creates a new instance of that forwards events to + /// Creates a new instance of that forwards events to . /// /// The level of events to enable. public static AzureEventSourceListener CreateConsoleLogger(EventLevel level = EventLevel.Informational) @@ -72,7 +80,7 @@ public static AzureEventSourceListener CreateConsoleLogger(EventLevel level = Ev } /// - /// Creates a new instance of that forwards events to + /// Creates a new instance of that forwards events to . /// /// The level of events to enable. public static AzureEventSourceListener CreateTraceLogger(EventLevel level = EventLevel.Informational) diff --git a/sdk/core/Azure.Core/src/DiagnosticsOptions.cs b/sdk/core/Azure.Core/src/DiagnosticsOptions.cs index 9b49616a2f9e..485f2b986ea1 100644 --- a/sdk/core/Azure.Core/src/DiagnosticsOptions.cs +++ b/sdk/core/Azure.Core/src/DiagnosticsOptions.cs @@ -3,9 +3,13 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace Azure.Core { + /// + /// Exposes client options related to logging, telemetry and distributed tracing. + /// public class DiagnosticsOptions { private const int MaxApplicationIdLength = 24; @@ -26,10 +30,21 @@ internal DiagnosticsOptions() LoggedQueryParameters = new List(); } + /// + /// Get or sets value indicating whether HTTP pipeline logging is enabled. + /// public bool IsLoggingEnabled { get; set; } = true; + /// + /// Gets or sets value indicating whether distributed tracing spans are going to be created for this clients methods calls and HTTP calls. + /// public bool IsDistributedTracingEnabled { get; set; } = true; + /// + /// Gets or sets value indicating whether the "User-Agent" header containing , client library package name and version, + /// and should be sent. + /// The default value can be controlled process wide by setting AZURE_TELEMETRY_DISABLED to true, false, 1 or 0. + /// public bool IsTelemetryEnabled { get; set; } /// @@ -52,6 +67,9 @@ internal DiagnosticsOptions() /// public IList LoggedQueryParameters { get; } + /// + /// Gets or sets the value sent a the first part of "User-Agent" headers for all requests issues by this client. Defaults to . + /// public string? ApplicationId { get => _applicationId; @@ -65,6 +83,9 @@ public string? ApplicationId } } + /// + /// Gets or sets the default application id. Default application id would be set on all instances. + /// public static string? DefaultApplicationId { get; set; } private static bool? EnvironmentVariableToBool(string value) diff --git a/sdk/core/Azure.Core/src/ETag.cs b/sdk/core/Azure.Core/src/ETag.cs index f395e801189b..59a8fd2ea1a0 100644 --- a/sdk/core/Azure.Core/src/ETag.cs +++ b/sdk/core/Azure.Core/src/ETag.cs @@ -2,10 +2,12 @@ // Licensed under the MIT License. using System; -using System.Data; namespace Azure { + /// + /// Represents an HTTP ETag. + /// public readonly struct ETag : IEquatable { private const char QuoteCharacter = '"'; @@ -13,34 +15,63 @@ namespace Azure private readonly string _value; + /// + /// Creates a new instance of . + /// + /// The string value of the ETag. public ETag(string etag) => _value = etag; + /// + /// Compares equality of two instances. + /// + /// The to compare. + /// The to compare to. + /// true if values of both ETags are equal, otherwise. false public static bool operator ==(ETag left, ETag right) => left.Equals(right); + /// + /// Compares inequality of two instances. + /// + /// The to compare. + /// The to compare to. + /// true if values of both ETags are not equal, otherwise. false public static bool operator !=(ETag left, ETag right) => !left.Equals(right); + /// + /// Instance of with the value. * + /// public static readonly ETag All = new ETag("*"); + /// public bool Equals(ETag other) { return string.Equals(_value, other._value, StringComparison.Ordinal); } - + /// + /// Indicates whether the value of current is equal to the provided string. + /// An object to compare with this object. + /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(string? other) { return string.Equals(_value, other, StringComparison.Ordinal); } + /// public override bool Equals(object? obj) { return (obj is ETag other) && Equals(other); } + /// public override int GetHashCode() { return _value?.GetHashCode() ?? 0; } + /// + /// + /// + /// The string representation of this . public override string ToString() { return _value ?? ""; diff --git a/sdk/core/Azure.Core/src/HttpHeader.cs b/sdk/core/Azure.Core/src/HttpHeader.cs index 2fe0b40d71ad..56f7ba61a188 100644 --- a/sdk/core/Azure.Core/src/HttpHeader.cs +++ b/sdk/core/Azure.Core/src/HttpHeader.cs @@ -5,8 +5,16 @@ namespace Azure.Core { + /// + /// Represents an HTTP header. + /// public readonly struct HttpHeader : IEquatable { + /// + /// Creates a new instance of with provided name and value. + /// + /// The header name. + /// The header value. public HttpHeader(string name, string value) { if (string.IsNullOrEmpty(name)) @@ -18,10 +26,17 @@ public HttpHeader(string name, string value) Value = value; } + /// + /// Gets header name. + /// public string Name { get; } + /// + /// Gets header value. If header has multiple values they would be joined with a comma. To get separate values use or . + /// public string Value { get; } + /// public override int GetHashCode() { var hashCode = new HashCodeBuilder(); @@ -30,6 +45,7 @@ public override int GetHashCode() return hashCode.ToHashCode(); } + /// public override bool Equals(object? obj) { if (obj is HttpHeader header) @@ -39,36 +55,89 @@ public override bool Equals(object? obj) return false; } + /// public override string ToString() => $"{Name}:{Value}"; + /// public bool Equals(HttpHeader other) { return string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase) && Value.Equals(other.Value, StringComparison.Ordinal); } #pragma warning disable CA1034 // Nested types should not be visible + /// + /// Contains names of commonly used headers. + /// public static class Names #pragma warning restore CA1034 // Nested types should not be visible { + /// + /// Returns. "Date" + /// public static string Date => "Date"; + /// + /// Returns. "x-ms-date" + /// public static string XMsDate => "x-ms-date"; + /// + /// Returns. "Content-Type" + /// public static string ContentType => "Content-Type"; + /// + /// Returns. "Content-Length" + /// public static string ContentLength => "Content-Length"; + /// + /// Returns. "ETag" + /// public static string ETag => "ETag"; + /// + /// Returns. "x-ms-request-id" + /// public static string XMsRequestId => "x-ms-request-id"; + /// + /// Returns. "User-Agent" + /// public static string UserAgent => "User-Agent"; + /// + /// Returns. "Accept" + /// public static string Accept => "Accept"; + /// + /// Returns. "Authorization" + /// public static string Authorization => "Authorization"; + /// + /// Returns. "Range" + /// public static string Range => "Range"; + /// + /// Returns. "x-ms-range" + /// public static string XMsRange => "x-ms-range"; + /// + /// Returns. "If-Match" + /// public static string IfMatch => "If-Match"; + /// + /// Returns. "If-None-Match" + /// public static string IfNoneMatch => "If-None-Match"; + /// + /// Returns. "If-Modified-Since" + /// public static string IfModifiedSince => "If-Modified-Since"; + /// + /// Returns. "If-Unmodified-Since" + /// public static string IfUnmodifiedSince => "If-Unmodified-Since"; } #pragma warning disable CA1034 // Nested types should not be visible #pragma warning disable CA1724 // Type name conflicts with standard namespace + /// + /// Commonly defined header values. + /// public static class Common #pragma warning restore CA1034 // Nested types should not be visible #pragma warning restore CA1724 // Type name conflicts with standard namespace @@ -77,9 +146,21 @@ public static class Common private const string ApplicationOctetStream = "application/octet-stream"; private const string ApplicationFormUrlEncoded = "application/x-www-form-urlencoded"; + /// + /// Returns header with name "ContentType" and value "application/json". + /// public static readonly HttpHeader JsonContentType = new HttpHeader(Names.ContentType, ApplicationJson); + /// + /// Returns header with name "Accept" and value "application/json". + /// public static readonly HttpHeader JsonAccept = new HttpHeader(Names.Accept, ApplicationJson); + /// + /// Returns header with name "ContentType" and value "application/octet-stream". + /// public static readonly HttpHeader OctetStreamContentType = new HttpHeader(Names.ContentType, ApplicationOctetStream); + /// + /// Returns header with name "ContentType" and value "application/x-www-form-urlencoded". + /// public static readonly HttpHeader FormUrlEncodedContentType = new HttpHeader(Names.ContentType, ApplicationFormUrlEncoded); } } diff --git a/sdk/core/Azure.Core/src/HttpMessage.cs b/sdk/core/Azure.Core/src/HttpMessage.cs index 18d4cf9bada0..6045e2cae62e 100644 --- a/sdk/core/Azure.Core/src/HttpMessage.cs +++ b/sdk/core/Azure.Core/src/HttpMessage.cs @@ -1,21 +1,28 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable enable - using System; using System.Collections.Generic; using System.IO; using System.Threading; +using Azure.Core.Pipeline; namespace Azure.Core { + /// + /// Represents a context flowing through the . + /// public sealed class HttpMessage: IDisposable { private Dictionary? _properties; private Response? _response; + /// + /// Creates a new instance of . + /// + /// The request. + /// The response classifier. public HttpMessage(Request request, ResponseClassifier responseClassifier) { Request = request; @@ -23,8 +30,15 @@ public HttpMessage(Request request, ResponseClassifier responseClassifier) BufferResponse = true; } + /// + /// Gets the associated with this message. + /// public Request Request { get; } + /// + /// Gets the associated with this message. Throws an exception if it wasn't set yet. + /// To avoid the exception use property to check. + /// public Response Response { get @@ -40,10 +54,19 @@ public Response Response set => _response = value; } + /// + /// Gets the value indicating if the response is set on this message. + /// public bool HasResponse => _response != null; + /// + /// The instance to use for response classification during pipeline invocation. + /// public CancellationToken CancellationToken { get; internal set; } + /// + /// The instance to use for response classification during pipeline invocation. + /// public ResponseClassifier ResponseClassifier { get; } /// @@ -51,12 +74,23 @@ public Response Response /// public bool BufferResponse { get; set; } + /// + /// Gets a property that modifies the pipeline behavior. Please refer to individual policies documentation on what properties it supports. + /// + /// The property name. + /// The property value. + /// true if property exists, otherwise. false. public bool TryGetProperty(string name, out object? value) { value = null; return _properties?.TryGetValue(name, out value) == true; } + /// + /// Sets a property that modifies the pipeline behavior. Please refer to individual policies documentation on what properties it supports. + /// + /// The property name. + /// The property value. public void SetProperty(string name, object value) { _properties ??= new Dictionary(); @@ -64,6 +98,10 @@ public void SetProperty(string name, object value) _properties[name] = value; } + /// + /// Returns the response content stream and releases it ownership to the caller. After calling this methods using would result in exception. + /// + /// The content stream or null if response didn't have any. public Stream? ExtractResponseContent() { switch (_response?.ContentStream) @@ -78,6 +116,9 @@ public void SetProperty(string name, object value) } } + /// + /// Disposes the request and response. + /// public void Dispose() { Request?.Dispose(); diff --git a/sdk/core/Azure.Core/src/HttpRange.cs b/sdk/core/Azure.Core/src/HttpRange.cs index 36b3de5612ad..7de93135e84b 100644 --- a/sdk/core/Azure.Core/src/HttpRange.cs +++ b/sdk/core/Azure.Core/src/HttpRange.cs @@ -29,10 +29,10 @@ namespace Azure public long? Length { get; } /// - /// Creates an instance of HttpRange + /// Creates an instance of HttpRange. /// /// The starting offset of the . Defaults to 0. - /// The lenght of the range. null means to the end + /// The length of the range. null means to the end. public HttpRange(long offset = 0, long? length = default) { if (offset < 0) diff --git a/sdk/core/Azure.Core/src/Operation{T}.cs b/sdk/core/Azure.Core/src/Operation{T}.cs index e747447b8df7..26251e81b80c 100644 --- a/sdk/core/Azure.Core/src/Operation{T}.cs +++ b/sdk/core/Azure.Core/src/Operation{T}.cs @@ -26,7 +26,7 @@ public abstract class Operation where T : notnull /// Final result of the LRO. /// /// - /// This property can be accessed only after the operation completes succesfully (HasValue is true). + /// This property can be accessed only after the operation completes successfully (HasValue is true). /// public abstract T Value { get; } @@ -46,7 +46,7 @@ public abstract class Operation where T : notnull public abstract bool HasCompleted { get; } /// - /// Returns true if the LRO completed succesfully and has produced final result (accessible by Value property). + /// Returns true if the LRO completed successfully and has produced final result (accessible by Value property). /// public abstract bool HasValue { get; } @@ -95,12 +95,15 @@ public abstract class Operation where T : notnull /// public abstract Response UpdateStatus(CancellationToken cancellationToken = default); + /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) => base.Equals(obj); + /// [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() => base.GetHashCode(); + /// [EditorBrowsable(EditorBrowsableState.Never)] public override string ToString() => base.ToString(); } diff --git a/sdk/core/Azure.Core/src/Pageable.cs b/sdk/core/Azure.Core/src/Pageable.cs index a5bda71995ba..5b410de07e3c 100644 --- a/sdk/core/Azure.Core/src/Pageable.cs +++ b/sdk/core/Azure.Core/src/Pageable.cs @@ -8,6 +8,11 @@ namespace Azure { + /// + /// A collection of values that may take multiple service requests to + /// iterate over. + /// + /// The type of the values. public abstract class Pageable : IEnumerable where T : notnull { /// @@ -36,7 +41,7 @@ protected Pageable(CancellationToken cancellationToken) => /// /// Enumerate the values a at a time. This may - /// make mutliple service requests. + /// make multiple service requests. /// /// /// A continuation token indicating where to resume paging or null to diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs index be3d989f3f34..cf5762aa9b1d 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs @@ -12,7 +12,7 @@ public abstract class HttpPipelinePolicy { /// /// Applies the policy to the . Implementers are expected to mutate before calling and observe the changes after. - /// Last policy in the pipeline is expected to set the + /// Last policy in the pipeline is expected to set the . /// /// The this policy would be applied to. /// The set of to execute after current one. diff --git a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxy.cs b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxy.cs index 9a482238effa..b6c91fd89419 100644 --- a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxy.cs @@ -236,7 +236,7 @@ private bool IsMatchInBypassList(Uri input) } /// - /// Gets the proxy URI. (iWebProxy interface) + /// Gets the proxy URI. (iWebProxy interface). /// public Uri GetProxy(Uri uri) { diff --git a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxyCredentials.cs b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxyCredentials.cs index a2897443ccb7..664b2e7553e9 100644 --- a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxyCredentials.cs +++ b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxyCredentials.cs @@ -58,7 +58,7 @@ public static HttpEnvironmentProxyCredentials TryCreate(Uri httpProxy, Uri https } /// - /// Converts string containing user:password to NetworkCredential object + /// Converts string containing user:password to NetworkCredential object. /// private static NetworkCredential GetCredentialsFromString(string value) { diff --git a/sdk/core/Azure.Core/src/RequestConditions.cs b/sdk/core/Azure.Core/src/RequestConditions.cs index 01c81a2eb9e2..5b37d18f4a8b 100644 --- a/sdk/core/Azure.Core/src/RequestConditions.cs +++ b/sdk/core/Azure.Core/src/RequestConditions.cs @@ -5,6 +5,9 @@ namespace Azure { + /// + /// Specifies HTTP options for conditional requests based on modification time. + /// public class RequestConditions : MatchConditions { /// @@ -15,7 +18,7 @@ public class RequestConditions : MatchConditions /// /// Optionally limit requests to resources that have remained - /// unmodified + /// unmodified. /// public DateTimeOffset? IfUnmodifiedSince { get; set; } } diff --git a/sdk/core/Azure.Core/src/RequestContent.cs b/sdk/core/Azure.Core/src/RequestContent.cs index c91ef46850c3..d30d4091defa 100644 --- a/sdk/core/Azure.Core/src/RequestContent.cs +++ b/sdk/core/Azure.Core/src/RequestContent.cs @@ -10,23 +10,71 @@ namespace Azure.Core { + /// + /// Represents the content sent as part of the . + /// public abstract class RequestContent : IDisposable { + /// + /// Creates an instance of that wraps a . + /// + /// The to use. + /// An instance of that wraps a . public static RequestContent Create(Stream stream) => new StreamContent(stream); + + /// + /// Creates an instance of that wraps an of . + /// + /// The of to use. + /// An instance of that wraps provided of . public static RequestContent Create(byte[] bytes) => new ArrayContent(bytes, 0, bytes.Length); + /// + /// Creates an instance of that wraps an of . + /// + /// The of to use. + /// The offset in to start from. + /// The length of the segment to use. + /// An instance of that wraps provided of . public static RequestContent Create(byte[] bytes, int index, int length) => new ArrayContent(bytes, index, length); + /// + /// Creates an instance of that wraps a . + /// + /// The to use. + /// An instance of that wraps a . public static RequestContent Create(ReadOnlyMemory bytes) => new MemoryContent(bytes); + /// + /// Creates an instance of that wraps a . + /// + /// The to use. + /// An instance of that wraps a . public static RequestContent Create(ReadOnlySequence bytes) => new ReadOnlySequenceContent(bytes); + /// + /// Writes contents of this object to an instance of . + /// + /// The stream to write to. + /// To cancellation token to use. public abstract Task WriteToAsync(Stream stream, CancellationToken cancellation); + /// + /// Writes contents of this object to an instance of . + /// + /// The stream to write to. + /// To cancellation token to use. public abstract void WriteTo(Stream stream, CancellationToken cancellation); + /// + /// Attempts to compute the length of the underlying content, if available. + /// + /// The length of the underlying data. public abstract bool TryComputeLength(out long length); + /// + /// Frees resources held by the object. + /// public abstract void Dispose(); private sealed class StreamContent : RequestContent @@ -107,8 +155,6 @@ public ArrayContent(byte[] bytes, int index, int length) _contentLength = length; } - public ReadOnlyMemory Bytes => _bytes.AsMemory(_contentStart, _contentLength); - public override void Dispose() { } public override void WriteTo(Stream stream, CancellationToken cancellation) diff --git a/sdk/core/Azure.Core/src/RequestFailedException.cs b/sdk/core/Azure.Core/src/RequestFailedException.cs index 0c1ed7c61bd7..135e38f58d3f 100644 --- a/sdk/core/Azure.Core/src/RequestFailedException.cs +++ b/sdk/core/Azure.Core/src/RequestFailedException.cs @@ -11,7 +11,7 @@ namespace Azure public class RequestFailedException : Exception { /// - /// Gets the HTTP status code of the response. Returns 0 if response was not received. + /// Gets the HTTP status code of the response. Returns. 0 if response was not received. /// public int Status { get; } diff --git a/sdk/core/Azure.Core/src/RequestHeaders.cs b/sdk/core/Azure.Core/src/RequestHeaders.cs index 4bff52e975ab..1a71dba435c6 100644 --- a/sdk/core/Azure.Core/src/RequestHeaders.cs +++ b/sdk/core/Azure.Core/src/RequestHeaders.cs @@ -7,6 +7,9 @@ namespace Azure.Core { + /// + /// Headers to be sent as part of the . + /// public readonly struct RequestHeaders : IEnumerable { private readonly Request _request; @@ -16,46 +19,91 @@ internal RequestHeaders(Request request) _request = request; } + /// + /// Returns an enumerator that iterates through the . + /// + /// A for the . public IEnumerator GetEnumerator() { return _request.EnumerateHeaders().GetEnumerator(); } + /// + /// Returns an enumerator that iterates through the . + /// + /// A for the . IEnumerator IEnumerable.GetEnumerator() { return _request.EnumerateHeaders().GetEnumerator(); } + /// + /// Adds the instance to the collection. + /// + /// The header to add. public void Add(HttpHeader header) { _request.AddHeader(header.Name, header.Value); } + /// + /// Adds the header to the collection. If a header with this name already exist adds an additional value to the header values. + /// + /// The header name. + /// The header value. public void Add(string name, string value) { _request.AddHeader(name, value); } + /// + /// Returns header value if headers is stored in the collection. If header has multiple values they are going to be joined with a comma. + /// + /// The header name. + /// The reference to populate with value. + /// true if the specified header is stored in the collection, otherwise. false public bool TryGetValue(string name, [NotNullWhen(true)] out string? value) { return _request.TryGetHeader(name, out value); } + /// + /// Returns header values if headers is stored in the collection. + /// + /// The header name. + /// The reference to populate with values. + /// true if the specified header is stored in the collection, otherwise. false public bool TryGetValues(string name, [NotNullWhen(true)] out IEnumerable? values) { return _request.TryGetHeaderValues(name, out values); } + + /// + /// Returns if headers is stored in the collection. + /// + /// The header name. + /// true if the specified header is stored in the collection, otherwise. false public bool Contains(string name) { return _request.ContainsHeader(name); } + /// + /// Sets the header value name. If a header with this name already exist replaces it's value. + /// + /// The header name. + /// The header value. public void SetValue(string name, string value) { _request.SetHeader(name, value); } + /// + /// Removes the header from the collection. + /// + /// The header name. + /// true if header existed, otherwise. false public bool Remove(string name) { return _request.RemoveHeader(name); diff --git a/sdk/core/Azure.Core/src/RequestMethod.cs b/sdk/core/Azure.Core/src/RequestMethod.cs index ea5ce1de42c0..d2c5b13348d1 100644 --- a/sdk/core/Azure.Core/src/RequestMethod.cs +++ b/sdk/core/Azure.Core/src/RequestMethod.cs @@ -5,17 +5,46 @@ namespace Azure.Core { + /// + /// Represents HTTP methods sent as part of a . + /// public readonly struct RequestMethod : IEquatable { + /// + /// Gets the HTTP method. + /// public string Method { get; } + /// + /// Gets instance for GET method. + /// public static RequestMethod Get { get; } = new RequestMethod("GET"); + /// + /// Gets instance for POST method. + /// public static RequestMethod Post { get; } = new RequestMethod("POST"); + /// + /// Gets instance for PUT method. + /// public static RequestMethod Put { get; } = new RequestMethod("PUT"); + /// + /// Gets instance for PATCH method. + /// public static RequestMethod Patch { get; } = new RequestMethod("PATCH"); + /// + /// Gets instance for DELETE method. + /// public static RequestMethod Delete { get; } = new RequestMethod("DELETE"); + /// + /// Gets instance for HEAD method. + /// public static RequestMethod Head { get; } = new RequestMethod("HEAD"); + /// + /// Creates an instance of with provided method. Method must be all uppercase. + /// Prefer if can be one of predefined method names. + /// + /// The method to use. public RequestMethod(string method) { Argument.AssertNotNull(method, nameof(method)); @@ -23,6 +52,10 @@ public RequestMethod(string method) Method = method.ToUpperInvariant(); } + /// + /// Parses string to it's representation. + /// + /// The method string to parse. public static RequestMethod Parse(string method) { Argument.AssertNotNull(method, nameof(method)); @@ -66,31 +99,47 @@ public static RequestMethod Parse(string method) return new RequestMethod(method); } + /// public bool Equals(RequestMethod other) { return string.Equals(Method, other.Method, StringComparison.Ordinal); } + /// public override bool Equals(object? obj) { return obj is RequestMethod other && Equals(other); } + /// public override int GetHashCode() { return Method?.GetHashCode() ?? 0; } + /// + /// Compares equality of two instances. + /// + /// The method to compare. + /// The method to compare against. + /// true if values are equal for and , otherwise. false public static bool operator ==(RequestMethod left, RequestMethod right) { return left.Equals(right); } + /// + /// Compares inequality of two instances. + /// + /// The method to compare. + /// The method to compare against. + /// true if values are equal for and , otherwise. false public static bool operator !=(RequestMethod left, RequestMethod right) { return !left.Equals(right); } + /// public override string ToString() { return Method ?? ""; diff --git a/sdk/core/Azure.Core/src/RequestUriBuilder.cs b/sdk/core/Azure.Core/src/RequestUriBuilder.cs index 423e9598ba19..3b3868de8378 100644 --- a/sdk/core/Azure.Core/src/RequestUriBuilder.cs +++ b/sdk/core/Azure.Core/src/RequestUriBuilder.cs @@ -6,6 +6,9 @@ namespace Azure.Core { + /// + /// Provides a custom constructor for uniform resource identifiers (URIs) and modifies URIs for the class. + /// public class RequestUriBuilder { private const char QuerySeparator = '?'; @@ -24,6 +27,9 @@ public class RequestUriBuilder private string? _scheme; + /// + /// Gets or sets the scheme name of the URI. + /// public string? Scheme { get => _scheme; @@ -34,6 +40,9 @@ public string? Scheme } } + /// + /// Gets or sets the Domain Name System (DNS) host name or IP address of a server. + /// public string? Host { get => _host; @@ -44,6 +53,9 @@ public string? Host } } + /// + /// Gets or sets the port number of the URI. + /// public int Port { get => _port; @@ -54,6 +66,9 @@ public int Port } } + /// + /// Gets or sets any query information included in the URI. + /// public string Query { get => HasQuery ? _pathAndQuery.ToString(_queryIndex, _pathAndQuery.Length - _queryIndex) : string.Empty; @@ -78,6 +93,9 @@ public string Query } } + /// + /// Gets or sets the password associated with the user that accesses the URI and the query information. + /// public string Path { get => HasQuery ? _pathAndQuery.ToString(0, _queryIndex) : _pathAndQuery.ToString(); @@ -103,8 +121,15 @@ public string Path private int PathLength => HasQuery ? _queryIndex : _pathAndQuery.Length; + /// + /// Gets the path to the resource referenced by the URI. + /// public string PathAndQuery => _pathAndQuery.ToString(); + /// + /// Replaces values inside this instance with values provided in parameter. + /// + /// The instance to get values from. public void Reset(Uri value) { Scheme = value.Scheme; @@ -115,6 +140,12 @@ public void Reset(Uri value) _uri = value; } + /// + /// Gets the instance constructed by the specified instance. + /// + /// + /// A that contains the URI constructed by the . + /// public Uri ToUri() { if (_uri == null) @@ -125,11 +156,22 @@ public Uri ToUri() return _uri; } + /// + /// Appends a query parameter adding separator if required. Escapes the value. + /// + /// The name of parameter. + /// The value of parameter. public void AppendQuery(string name, string value) { AppendQuery(name, value, true); } + /// + /// Appends a query parameter adding separator if required. + /// + /// The name of parameter. + /// The value of parameter. + /// Whether value should be escaped. public void AppendQuery(string name, string value, bool escapeValue) { ResetUri(); @@ -152,11 +194,20 @@ public void AppendQuery(string name, string value, bool escapeValue) _pathAndQuery.Append(value); } + /// + /// Appends escaped to without adding path separator. + /// + /// The value to append. public void AppendPath(string value) { AppendPath(value, escape: true); } + /// + /// Appends optionally escaped to without adding path separator. + /// + /// The value to append. + /// Whether value should be escaped. public void AppendPath(string value, bool escape) { if (string.IsNullOrEmpty(value)) @@ -195,6 +246,10 @@ public void AppendPath(string value, bool escape) } } + /// + /// Returns a string representation of this i. + /// + /// public override string ToString() { return ToString(null, string.Empty); diff --git a/sdk/core/Azure.Core/src/ResponseClassifier.cs b/sdk/core/Azure.Core/src/ResponseClassifier.cs index b936e0a0fc30..9e31cc5cc854 100644 --- a/sdk/core/Azure.Core/src/ResponseClassifier.cs +++ b/sdk/core/Azure.Core/src/ResponseClassifier.cs @@ -3,14 +3,13 @@ using System; using System.IO; -using Azure.Core.Pipeline; namespace Azure.Core { public class ResponseClassifier { /// - /// Specifies if the response should terminate the pipeline and not be retried. + /// Specifies if the request should be retried. /// public virtual bool IsRetriableResponse(HttpMessage message) { @@ -18,7 +17,7 @@ public virtual bool IsRetriableResponse(HttpMessage message) } /// - /// Specifies if the exception should terminate the pipeline and not be retried. + /// Specifies if the operation that caused the exception should be retried. /// public virtual bool IsRetriableException(Exception exception) { diff --git a/sdk/core/Azure.Core/src/ResponseHeaders.cs b/sdk/core/Azure.Core/src/ResponseHeaders.cs index c6091d55304a..5617c4be9afd 100644 --- a/sdk/core/Azure.Core/src/ResponseHeaders.cs +++ b/sdk/core/Azure.Core/src/ResponseHeaders.cs @@ -9,6 +9,9 @@ namespace Azure.Core { + /// + /// Headers received as part of the . + /// public readonly struct ResponseHeaders : IEnumerable { private readonly Response _response; @@ -18,40 +21,81 @@ internal ResponseHeaders(Response response) _response = response; } + /// + /// Gets the parsed value of "Date" or "x-ms-date" header. + /// public DateTimeOffset? Date => TryGetValue(HttpHeader.Names.Date, out var value) || TryGetValue(HttpHeader.Names.XMsDate, out value) ? (DateTimeOffset?)DateTimeOffset.Parse(value, CultureInfo.InvariantCulture) : null; + /// + /// Gets the value of "Content-Type" header. + /// public string? ContentType => TryGetValue(HttpHeader.Names.ContentType, out string? value) ? value : null; + /// + /// Gets the parsed value of "Content-Length" header. + /// public int? ContentLength => TryGetValue(HttpHeader.Names.ContentLength, out string? stringValue) ? int.Parse(stringValue, CultureInfo.InvariantCulture) : (int?)null; + /// + /// Gets the parsed value of "ETag" header. + /// public ETag? ETag => TryGetValue(HttpHeader.Names.ETag, out string? stringValue) ? Azure.ETag.Parse(stringValue) : (ETag?)null; + /// + /// Gets the value of "x-ms-request-id" header. + /// public string? RequestId => TryGetValue(HttpHeader.Names.XMsRequestId, out string? value) ? value : null; + /// + /// Returns an enumerator that iterates through the . + /// + /// A for the . public IEnumerator GetEnumerator() { return _response.EnumerateHeaders().GetEnumerator(); } + /// + /// Returns an enumerator that iterates through the . + /// + /// A for the . IEnumerator IEnumerable.GetEnumerator() { return _response.EnumerateHeaders().GetEnumerator(); } + /// + /// Returns header value if headers is stored in the collection. If header has multiple values they are going to be joined with a comma. + /// + /// The header name. + /// The reference to populate with value. + /// true if the specified header is stored in the collection, otherwise. false public bool TryGetValue(string name, [NotNullWhen(true)] out string? value) { return _response.TryGetHeader(name, out value); } + /// + /// Returns header values if headers is stored in the collection. + /// + /// The header name. + /// The reference to populate with values. + /// true if the specified header is stored in the collection, otherwise. false public bool TryGetValues(string name, [NotNullWhen(true)] out IEnumerable? values) { return _response.TryGetHeaderValues(name, out values); } + + /// + /// Returns if headers is stored in the collection. + /// + /// The header name. + /// true if the specified header is stored in the collection, otherwise. false public bool Contains(string name) { return _response.ContainsHeader(name); diff --git a/sdk/core/Azure.Core/src/Response{T}.cs b/sdk/core/Azure.Core/src/Response{T}.cs index b5f1098591ce..a37c3a967d22 100644 --- a/sdk/core/Azure.Core/src/Response{T}.cs +++ b/sdk/core/Azure.Core/src/Response{T}.cs @@ -5,20 +5,38 @@ namespace Azure { + /// + /// Represents a result of Azure operation. + /// + /// The type of returned value. public abstract class Response { + /// + /// Returns the HTTP response returned by the service. + /// + /// The HTTP response returned by the service. public abstract Response GetRawResponse(); + /// + /// Gets the value returned by the service. + /// public abstract T Value { get; } + /// + /// Returns the value of this object. + /// + /// The instance. public static implicit operator T(Response response) => response.Value; + /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object? obj) => base.Equals(obj); + /// [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() => base.GetHashCode(); + /// [EditorBrowsable(EditorBrowsableState.Never)] public override string ToString() => base.ToString(); } diff --git a/sdk/core/Azure.Core/src/Shared/DiagnosticScope.cs b/sdk/core/Azure.Core/src/Shared/DiagnosticScope.cs index b1b4081a2370..061ac46d0375 100644 --- a/sdk/core/Azure.Core/src/Shared/DiagnosticScope.cs +++ b/sdk/core/Azure.Core/src/Shared/DiagnosticScope.cs @@ -117,7 +117,7 @@ public void AddLink(Activity activity) /// /// HACK HACK HACK. Some runtime environments like Azure.Functions downgrade System.Diagnostic.DiagnosticSource package version causing method not found exceptions in customer apps - /// This type is a temporary workaround to avoid the issue + /// This type is a temporary workaround to avoid the issue. /// internal static class ActivityExtensions { diff --git a/sdk/core/Azure.Core/src/Shared/HashCodeBuilder.cs b/sdk/core/Azure.Core/src/Shared/HashCodeBuilder.cs index b1bd8404d41a..301db77ec72d 100644 --- a/sdk/core/Azure.Core/src/Shared/HashCodeBuilder.cs +++ b/sdk/core/Azure.Core/src/Shared/HashCodeBuilder.cs @@ -8,7 +8,7 @@ namespace Azure.Core { /// - /// Copied from https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/HashCode.cs + /// Copied from https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/HashCode.cs. /// internal struct HashCodeBuilder { diff --git a/sdk/core/Azure.Core/src/TokenCredential.cs b/sdk/core/Azure.Core/src/TokenCredential.cs index 404206448d14..2705f1e09bc1 100644 --- a/sdk/core/Azure.Core/src/TokenCredential.cs +++ b/sdk/core/Azure.Core/src/TokenCredential.cs @@ -7,12 +7,24 @@ namespace Azure.Core { /// - /// Represents a credential capable of providing an OAuth token + /// Represents a credential capable of providing an OAuth token. /// public abstract class TokenCredential { + /// + /// Gets an for the specified set of scopes. + /// + /// The with authentication information. + /// The to use. + /// A valid . public abstract Task GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken); + /// + /// Gets an for the specified set of scopes. + /// + /// The with authentication information. + /// The to use. + /// A valid . public abstract AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken); } } diff --git a/sdk/core/Azure.Core/src/TokenRequestContext.cs b/sdk/core/Azure.Core/src/TokenRequestContext.cs index 10b5c4481240..53457af8495b 100644 --- a/sdk/core/Azure.Core/src/TokenRequestContext.cs +++ b/sdk/core/Azure.Core/src/TokenRequestContext.cs @@ -5,21 +5,21 @@ namespace Azure.Core { /// - /// Contains the details of an authentication token request + /// Contains the details of an authentication token request. /// public readonly struct TokenRequestContext { /// - /// Creates a new TokenRequest with the specified scopes + /// Creates a new TokenRequest with the specified scopes. /// - /// The scopes required for the token + /// The scopes required for the token. public TokenRequestContext(string[] scopes) { Scopes = scopes; } /// - /// The scopes required for the token + /// The scopes required for the token. /// public string[] Scopes { get; } } diff --git a/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs b/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs index 171d285d1a5e..dc044984fb5a 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs @@ -585,6 +585,11 @@ public async Task StartCopyFromUriAsync_Source_AccessConditionsFail() BlockBlobClient destBlob = InstrumentClient(container.GetBlockBlobClient(GetNewBlobName())); + Operation operation = await destBlob.StartCopyFromUriAsync(source: srcBlob.Uri); + await operation.WaitForCompletionAsync(); + + await destBlob.StartCopyFromUriAsync(source: srcBlob.Uri).WaitForCompletionAsync(); + // Act await TestHelper.AssertExpectedExceptionAsync( destBlob.StartCopyFromUriAsync(