From 4b9682d643019f54c3cd9b27fafaa2b2b8fd58bb Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 2 Feb 2024 16:42:39 -0800 Subject: [PATCH 01/47] Initial files --- .../src/Azure.Core.TestFramework.csproj | 5 +- sdk/core/Azure.Core/Azure.Core.sln | 50 +- sdk/core/Azure.Core/src/Azure.Core.csproj | 5 + sdk/core/Azure.Core/src/AzureKeyCredential.cs | 36 +- sdk/core/Azure.Core/src/ClientOptions.cs | 33 +- sdk/core/Azure.Core/src/DelayStrategy.cs | 48 +- sdk/core/Azure.Core/src/DiagnosticsOptions.cs | 95 ++- .../src/ExponentialDelayStrategy.cs | 9 +- sdk/core/Azure.Core/src/HttpMessage.cs | 133 ++-- .../Internal/AzureCorePipelineProcessor.cs | 65 ++ .../Azure.Core/src/NullableResponseOfT.cs | 47 +- .../Pipeline/HttpClientTransport.Adapter.cs | 56 ++ .../Pipeline/HttpClientTransport.Request.cs | 149 +++++ .../Pipeline/HttpClientTransport.Response.cs | 68 ++ .../src/Pipeline/HttpClientTransport.cs | 629 ++---------------- .../Azure.Core/src/Pipeline/HttpPipeline.cs | 62 +- .../src/Pipeline/HttpPipelineBuilder.cs | 8 +- .../src/Pipeline/HttpPipelinePolicy.cs | 58 +- .../src/Pipeline/HttpWebRequestTransport.cs | 100 ++- .../DefaultRequestFailedDetailsParser.cs | 39 +- .../Internal/HttpPipelineTransportPolicy.cs | 4 +- .../Pipeline/Internal/ResponseBodyPolicy.cs | 143 +--- .../Pipeline/RequestFailedDetailsParser.cs | 3 +- .../src/Pipeline/RetryPolicy.AzurePolicy.cs | 106 +++ .../Azure.Core/src/Pipeline/RetryPolicy.cs | 221 ++---- sdk/core/Azure.Core/src/Request.cs | 149 ++++- sdk/core/Azure.Core/src/RequestContent.cs | 56 +- sdk/core/Azure.Core/src/RequestContext.cs | 50 +- .../Azure.Core/src/RequestFailedException.cs | 187 +++--- sdk/core/Azure.Core/src/RequestUriBuilder.cs | 3 +- sdk/core/Azure.Core/src/Response.cs | 145 ++-- sdk/core/Azure.Core/src/ResponseClassifier.cs | 89 ++- sdk/core/Azure.Core/src/ResponseOfT.cs | 21 +- sdk/core/Azure.Core/src/RetryOptions.cs | 81 ++- .../Azure.Core/src/StatusCodeClassifier.cs | 63 +- .../tests/FailedResponseExceptionTests.cs | 2 +- .../tests/HttpPipelineFunctionalTests.cs | 3 +- .../tests/NullableResponseOfTTests.cs | 35 + sdk/core/Azure.Core/tests/PipelineTestBase.cs | 4 +- .../tests/ResponseBodyPolicyTests.cs | 6 +- .../Azure.Core/tests/RetryPolicyTestBase.cs | 9 +- .../common/Azure.Core.Tests.Common.csproj | 1 + 42 files changed, 1625 insertions(+), 1451 deletions(-) create mode 100644 sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs create mode 100644 sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs create mode 100644 sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs create mode 100644 sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs create mode 100644 sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs diff --git a/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj b/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj index df96d31e9076..519da9c09fa5 100644 --- a/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj +++ b/sdk/core/Azure.Core.TestFramework/src/Azure.Core.TestFramework.csproj @@ -4,7 +4,6 @@ true - @@ -40,4 +39,8 @@ <_Parameter2>$(NuGetPackageRoot)\azure.sdk.tools.testproxy\$(TestProxyVersion)\tools\net6.0\any\Azure.Sdk.Tools.TestProxy.dll + + + + diff --git a/sdk/core/Azure.Core/Azure.Core.sln b/sdk/core/Azure.Core/Azure.Core.sln index 194fb4694ad2..e7b54032ec97 100644 --- a/sdk/core/Azure.Core/Azure.Core.sln +++ b/sdk/core/Azure.Core/Azure.Core.sln @@ -53,15 +53,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.Tests.Public", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.Tests.Common", "tests\common\Azure.Core.Tests.Common.csproj", "{0EEDF53F-120A-45B1-8468-A97A0D46DBAC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel", "..\System.ClientModel\src\System.ClientModel.csproj", "{70B67A2C-3CA5-44A0-AF2D-51241A0076E2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel", "..\System.ClientModel\src\System.ClientModel.csproj", "{0EDC2FDC-6326-431D-86D2-02997F341934}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Client", "..\System.ClientModel\tests\client\System.ClientModel.Tests.Client.csproj", "{062EA07F-5F75-4447-9453-44FF8A99EF1B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests", "..\System.ClientModel\tests\System.ClientModel.Tests.csproj", "{55DBB83B-70E5-4591-BB74-668D8662FECB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal", "..\System.ClientModel\tests\internal\System.ClientModel.Tests.Internal.csproj", "{23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Client", "..\System.ClientModel\tests\client\System.ClientModel.Tests.Client.csproj", "{82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal.Perf", "..\System.ClientModel\tests\internal.perf\System.ClientModel.Tests.Internal.Perf.csproj", "{2E79B809-C520-4A07-8BC2-23C43B4D3C35}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal", "..\System.ClientModel\tests\internal\System.ClientModel.Tests.Internal.csproj", "{F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests", "..\System.ClientModel\tests\System.ClientModel.Tests.csproj", "{F317D37D-AA38-4557-A724-6ADA56281B77}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal.Perf", "..\System.ClientModel\tests\internal.perf\System.ClientModel.Tests.Internal.Perf.csproj", "{14F5E486-2C03-4293-ACA7-47B3E069956E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -141,26 +141,26 @@ Global {0EEDF53F-120A-45B1-8468-A97A0D46DBAC}.Debug|Any CPU.Build.0 = Debug|Any CPU {0EEDF53F-120A-45B1-8468-A97A0D46DBAC}.Release|Any CPU.ActiveCfg = Release|Any CPU {0EEDF53F-120A-45B1-8468-A97A0D46DBAC}.Release|Any CPU.Build.0 = Release|Any CPU - {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Release|Any CPU.Build.0 = Release|Any CPU - {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Release|Any CPU.Build.0 = Release|Any CPU - {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Release|Any CPU.Build.0 = Release|Any CPU - {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Release|Any CPU.Build.0 = Release|Any CPU - {F317D37D-AA38-4557-A724-6ADA56281B77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F317D37D-AA38-4557-A724-6ADA56281B77}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F317D37D-AA38-4557-A724-6ADA56281B77}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F317D37D-AA38-4557-A724-6ADA56281B77}.Release|Any CPU.Build.0 = Release|Any CPU + {0EDC2FDC-6326-431D-86D2-02997F341934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0EDC2FDC-6326-431D-86D2-02997F341934}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0EDC2FDC-6326-431D-86D2-02997F341934}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0EDC2FDC-6326-431D-86D2-02997F341934}.Release|Any CPU.Build.0 = Release|Any CPU + {55DBB83B-70E5-4591-BB74-668D8662FECB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55DBB83B-70E5-4591-BB74-668D8662FECB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55DBB83B-70E5-4591-BB74-668D8662FECB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55DBB83B-70E5-4591-BB74-668D8662FECB}.Release|Any CPU.Build.0 = Release|Any CPU + {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Debug|Any CPU.Build.0 = Debug|Any CPU + {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Release|Any CPU.ActiveCfg = Release|Any CPU + {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Release|Any CPU.Build.0 = Release|Any CPU + {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Release|Any CPU.Build.0 = Release|Any CPU + {14F5E486-2C03-4293-ACA7-47B3E069956E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14F5E486-2C03-4293-ACA7-47B3E069956E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14F5E486-2C03-4293-ACA7-47B3E069956E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14F5E486-2C03-4293-ACA7-47B3E069956E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/sdk/core/Azure.Core/src/Azure.Core.csproj b/sdk/core/Azure.Core/src/Azure.Core.csproj index e16d7472d3b0..ad0da6c41d3a 100644 --- a/sdk/core/Azure.Core/src/Azure.Core.csproj +++ b/sdk/core/Azure.Core/src/Azure.Core.csproj @@ -71,6 +71,11 @@ + + + + + diff --git a/sdk/core/Azure.Core/src/AzureKeyCredential.cs b/sdk/core/Azure.Core/src/AzureKeyCredential.cs index 75c68ffd2eab..91f9e7c521ad 100644 --- a/sdk/core/Azure.Core/src/AzureKeyCredential.cs +++ b/sdk/core/Azure.Core/src/AzureKeyCredential.cs @@ -1,9 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System.ClientModel; using System.ComponentModel; -using System.Threading; -using Azure.Core; namespace Azure { @@ -11,18 +10,21 @@ namespace Azure /// Key credential used to authenticate to an Azure Service. /// It provides the ability to update the key without creating a new client. /// - public class AzureKeyCredential + public class AzureKeyCredential : ApiKeyCredential { - private string _key; - /// /// Key used to authenticate to an Azure service. /// [EditorBrowsable(EditorBrowsableState.Never)] public string Key { - get => Volatile.Read(ref _key); - private set => Volatile.Write(ref _key, value); + get + { + Deconstruct(out string key); + return key; + } + + private set => Update(value); } /// @@ -35,26 +37,8 @@ public string Key /// /// Thrown when the is empty. /// -#pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. - public AzureKeyCredential(string key) => Update(key); -#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. - - /// - /// Updates the service key. - /// This is intended to be used when you've regenerated your service key - /// and want to update long lived clients. - /// - /// Key to authenticate the service against. - /// - /// Thrown when the is null. - /// - /// - /// Thrown when the is empty. - /// - public void Update(string key) + public AzureKeyCredential(string key) : base(key) { - Argument.AssertNotNullOrEmpty(key, nameof(key)); - Key = key; } } } diff --git a/sdk/core/Azure.Core/src/ClientOptions.cs b/sdk/core/Azure.Core/src/ClientOptions.cs index 25beb96f1a9e..5dc1067de00f 100644 --- a/sdk/core/Azure.Core/src/ClientOptions.cs +++ b/sdk/core/Azure.Core/src/ClientOptions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.ComponentModel; using Azure.Core.Pipeline; @@ -11,11 +12,13 @@ namespace Azure.Core /// /// Base type for all client option types, exposes various common client options like , , . /// - public abstract class ClientOptions + public abstract class ClientOptions : ClientPipelineOptions { private HttpPipelineTransport _transport; internal bool IsCustomTransportSet { get; private set; } + private HttpPipelinePolicy? _retryPolicy; + /// /// Gets the default set of . Changes to the options would be reflected /// in new instances of type created after changes to were made. @@ -71,11 +74,13 @@ internal ClientOptions(ClientOptions? clientOptions, DiagnosticsOptions? diagnos /// /// The to be used for this client. Defaults to an instance of . /// - public HttpPipelineTransport Transport + public new HttpPipelineTransport Transport { get => _transport; set { + AssertNotFrozen(); + _transport = value ?? throw new ArgumentNullException(nameof(value)); IsCustomTransportSet = true; } @@ -97,7 +102,16 @@ public HttpPipelineTransport Transport /// If is overridden or a custom is specified, /// it is the implementer's responsibility to update the values. /// - public HttpPipelinePolicy? RetryPolicy { get; set; } + public new HttpPipelinePolicy? RetryPolicy + { + get => _retryPolicy; + set + { + AssertNotFrozen(); + + _retryPolicy = value; + } + } /// /// Adds an policy into the client pipeline. The position of policy in the pipeline is controlled by the parameter. @@ -108,6 +122,8 @@ public HttpPipelineTransport Transport /// The position of policy in the pipeline. public void AddPolicy(HttpPipelinePolicy policy, HttpPipelinePosition position) { + AssertNotFrozen(); + if (position != HttpPipelinePosition.PerCall && position != HttpPipelinePosition.PerRetry && position != HttpPipelinePosition.BeforeTransport) @@ -132,5 +148,16 @@ public void AddPolicy(HttpPipelinePolicy policy, HttpPipelinePosition position) /// [EditorBrowsable(EditorBrowsableState.Never)] public override string? ToString() => base.ToString(); + + /// + /// TBD. + /// + public override void Freeze() + { + Diagnostics.Freeze(); + Retry.Freeze(); + + base.Freeze(); + } } } diff --git a/sdk/core/Azure.Core/src/DelayStrategy.cs b/sdk/core/Azure.Core/src/DelayStrategy.cs index c07e1960306c..89f71bd86b79 100644 --- a/sdk/core/Azure.Core/src/DelayStrategy.cs +++ b/sdk/core/Azure.Core/src/DelayStrategy.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable enable - using System; using Azure.Core.Pipeline; @@ -11,15 +9,14 @@ namespace Azure.Core /// /// An abstraction to control delay behavior. /// -#pragma warning disable AZC0012 // Avoid single word type names public abstract class DelayStrategy -#pragma warning restore AZC0012 // Avoid single word type names { + internal const double DefaultJitterFactor = 0.2; + private readonly Random _random = new ThreadSafeRandom(); private readonly double _minJitterFactor; private readonly double _maxJitterFactor; private readonly TimeSpan _maxDelay; - internal const double DefaultJitterFactor = 0.2; /// /// Constructs a new instance of . This constructor can be used by derived classes to customize the jitter factor and max delay. @@ -29,10 +26,11 @@ public abstract class DelayStrategy /// delay used will be a random double between 0.8 and 1.2. If set to 0, no jitter will be applied. protected DelayStrategy(TimeSpan? maxDelay = default, double jitterFactor = DefaultJitterFactor) { + _minJitterFactor = 1.0 - jitterFactor; + _maxJitterFactor = 1.0 + jitterFactor; + // use same defaults as RetryOptions - _minJitterFactor = 1 - jitterFactor; - _maxJitterFactor = 1 + jitterFactor; - _maxDelay = maxDelay ?? TimeSpan.FromMinutes(1); + _maxDelay = maxDelay ?? RetryOptions.DefaultMaxDelay; } /// @@ -45,7 +43,10 @@ public static DelayStrategy CreateExponentialDelayStrategy( TimeSpan? initialDelay = default, TimeSpan? maxDelay = default) { - return new ExponentialDelayStrategy(initialDelay ?? TimeSpan.FromSeconds(0.8), maxDelay ?? TimeSpan.FromMinutes(1)); + initialDelay ??= RetryOptions.DefaultInitialDelay; + maxDelay ??= RetryOptions.DefaultMaxDelay; + + return new ExponentialDelayStrategy(initialDelay, maxDelay); } /// @@ -53,11 +54,8 @@ public static DelayStrategy CreateExponentialDelayStrategy( /// /// The delay to use. /// The instance. - public static DelayStrategy CreateFixedDelayStrategy( - TimeSpan? delay = default) - { - return new FixedDelayStrategy(delay ?? TimeSpan.FromSeconds(0.8)); - } + public static DelayStrategy CreateFixedDelayStrategy(TimeSpan? delay = default) + => new FixedDelayStrategy(delay ?? RetryOptions.DefaultInitialDelay); /// /// Gets the next delay interval. Implement this method to provide custom delay logic. @@ -74,12 +72,16 @@ public static DelayStrategy CreateFixedDelayStrategy( /// The response, if any, returned from the service. /// The retry number. /// A representing the next delay interval. - public TimeSpan GetNextDelay(Response? response, int retryNumber) => - Max( - response?.Headers.RetryAfter ?? TimeSpan.Zero, - Min( - ApplyJitter(GetNextDelayCore(response, retryNumber)), - _maxDelay)); + public TimeSpan GetNextDelay(Response? response, int retryNumber) + { + TimeSpan retryAfter = response?.Headers.RetryAfter ?? TimeSpan.Zero; + + TimeSpan defaultDelay = GetNextDelayCore(response, retryNumber); + TimeSpan defaultWithJitter = ApplyJitter(defaultDelay); + TimeSpan cappedDefault = Min(defaultWithJitter, _maxDelay); + + return Max(retryAfter, cappedDefault); + } private TimeSpan ApplyJitter(TimeSpan delay) { @@ -99,7 +101,8 @@ private TimeSpan ApplyJitter(TimeSpan delay) /// The first value. /// The second value. /// The maximum of the two values. - protected static TimeSpan Max(TimeSpan val1, TimeSpan val2) => val1 > val2 ? val1 : val2; + protected static TimeSpan Max(TimeSpan val1, TimeSpan val2) + => val1 > val2 ? val1 : val2; /// /// Gets the minimum of two values. @@ -107,6 +110,7 @@ private TimeSpan ApplyJitter(TimeSpan delay) /// The first value. /// The second value. /// The minimum of the two values. - protected static TimeSpan Min(TimeSpan val1, TimeSpan val2) => val1 < val2 ? val1 : val2; + protected static TimeSpan Min(TimeSpan val1, TimeSpan val2) + => val1 < val2 ? val1 : val2; } } diff --git a/sdk/core/Azure.Core/src/DiagnosticsOptions.cs b/sdk/core/Azure.Core/src/DiagnosticsOptions.cs index bfec3b23b5da..afd5c48172cd 100644 --- a/sdk/core/Azure.Core/src/DiagnosticsOptions.cs +++ b/sdk/core/Azure.Core/src/DiagnosticsOptions.cs @@ -16,11 +16,20 @@ public class DiagnosticsOptions private string? _applicationId; + private bool _isLoggingEnabled = true; + private bool _isDistributedTracingEnabled = true; + private bool _isTelemetryEnabled; + private bool _isLoggingContentEnabled; + private int _loggedContentSizeLimit = 4 * 1024; + + private bool _frozen; + /// /// Creates a new instance of with default values. /// protected internal DiagnosticsOptions() : this(ClientOptions.Default.Diagnostics) - { } + { + } /// /// Initializes the newly created with the same settings as the specified . @@ -78,39 +87,84 @@ internal DiagnosticsOptions(DiagnosticsOptions? diagnosticsOptions) /// /// Get or sets value indicating whether HTTP pipeline logging is enabled. /// - public bool IsLoggingEnabled { get; set; } = true; + public bool IsLoggingEnabled + { + get => _isLoggingEnabled; + set + { + AssertNotFrozen(); + + _isLoggingEnabled = value; + } + } /// /// Gets or sets value indicating whether distributed tracing activities () are going to be created for the clients methods calls and HTTP calls. /// - public bool IsDistributedTracingEnabled { get; set; } = true; + public bool IsDistributedTracingEnabled + { + get => _isDistributedTracingEnabled; + set + { + AssertNotFrozen(); + + _isDistributedTracingEnabled = value; + } + } /// /// 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; } + public bool IsTelemetryEnabled + { + get => _isTelemetryEnabled; + set + { + AssertNotFrozen(); + + _isTelemetryEnabled = value; + } + } /// /// Gets or sets value indicating if request or response content should be logged. /// - public bool IsLoggingContentEnabled { get; set; } + public bool IsLoggingContentEnabled + { + get => _isLoggingContentEnabled; + set + { + AssertNotFrozen(); + + _isLoggingContentEnabled = value; + } + } /// /// Gets or sets value indicating maximum size of content to log in bytes. Defaults to 4096. /// - public int LoggedContentSizeLimit { get; set; } = 4 * 1024; + public int LoggedContentSizeLimit + { + get => _loggedContentSizeLimit; + set + { + AssertNotFrozen(); + + _loggedContentSizeLimit = value; + } + } /// /// Gets a list of header names that are not redacted during logging. /// - public IList LoggedHeaderNames { get; internal set; } + public IList LoggedHeaderNames { get; private set; } /// /// Gets a list of query parameter names that are not redacted during logging. /// - public IList LoggedQueryParameters { get; internal set; } + public IList LoggedQueryParameters { get; private set; } /// /// Gets or sets the value sent as the first part of "User-Agent" headers for all requests issues by this client. Defaults to . @@ -120,6 +174,8 @@ public string? ApplicationId get => _applicationId; set { + AssertNotFrozen(); + if (value != null && value.Length > MaxApplicationIdLength) { throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(ApplicationId)} must be shorter than {MaxApplicationIdLength + 1} characters"); @@ -153,5 +209,28 @@ public static string? DefaultApplicationId return null; } + + internal void Freeze() + { + _frozen = true; + + if (LoggedHeaderNames is List mutableHeaderNames) + { + LoggedHeaderNames = mutableHeaderNames.AsReadOnly(); + } + + if (LoggedQueryParameters is List mutableQueryParameters) + { + LoggedQueryParameters = mutableQueryParameters.AsReadOnly(); + } + } + + private void AssertNotFrozen() + { + if (_frozen) + { + throw new InvalidOperationException("Cannot change a ClientOptions instance after it has been used to create a client."); + } + } } } diff --git a/sdk/core/Azure.Core/src/ExponentialDelayStrategy.cs b/sdk/core/Azure.Core/src/ExponentialDelayStrategy.cs index c041756616ef..86f7a3280817 100644 --- a/sdk/core/Azure.Core/src/ExponentialDelayStrategy.cs +++ b/sdk/core/Azure.Core/src/ExponentialDelayStrategy.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable enable - using System; namespace Azure.Core @@ -11,11 +9,10 @@ internal class ExponentialDelayStrategy : DelayStrategy { private readonly TimeSpan _delay; - public ExponentialDelayStrategy( - TimeSpan? delay = default, - TimeSpan? maxDelay = default) : base(maxDelay) + public ExponentialDelayStrategy(TimeSpan? delay = default, TimeSpan? maxDelay = default) + : base(maxDelay) { - _delay = delay ?? TimeSpan.FromSeconds(0.8); + _delay = delay ?? RetryOptions.DefaultInitialDelay; } protected override TimeSpan GetNextDelayCore(Response? response, int retryNumber) => diff --git a/sdk/core/Azure.Core/src/HttpMessage.cs b/sdk/core/Azure.Core/src/HttpMessage.cs index 06e0fa598077..467b5dafa317 100644 --- a/sdk/core/Azure.Core/src/HttpMessage.cs +++ b/sdk/core/Azure.Core/src/HttpMessage.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.IO; using System.Threading; @@ -12,95 +13,79 @@ namespace Azure.Core /// /// Represents a context flowing through the . /// - public sealed class HttpMessage : IDisposable + public sealed class HttpMessage : PipelineMessage { - private ArrayBackedPropertyBag _propertyBag; - private Response? _response; - /// /// Creates a new instance of . /// /// The request. /// The response classifier. public HttpMessage(Request request, ResponseClassifier responseClassifier) + : base(request) { - Argument.AssertNotNull(request, nameof(Request)); - Request = request; + Argument.AssertNotNull(request, nameof(request)); + ResponseClassifier = responseClassifier; - BufferResponse = true; - _propertyBag = new ArrayBackedPropertyBag(); } /// /// Gets the associated with this message. /// - public Request Request { get; } + public new Request Request { get => (Request)base.Request; } /// /// 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 + public new Response Response { get { - if (_response == null) + if (base.Response is null) { #pragma warning disable CA1065 // Do not raise exceptions in unexpected locations throw new InvalidOperationException("Response was not set, make sure SendAsync was called"); #pragma warning restore CA1065 // Do not raise exceptions in unexpected locations } - return _response; + return (Response)base.Response; } - set => _response = value; + + set => base.Response = value; } /// /// Gets the value indicating if the response is set on this message. /// - public bool HasResponse => _response != null; + public bool HasResponse => base.Response is not null; - internal void ClearResponse() => _response = null; - - /// - /// The to be used during the processing. - /// - public CancellationToken CancellationToken { get; internal set; } + internal void ClearResponse() => Response = null!; /// /// The instance to use for response classification during pipeline invocation. /// - public ResponseClassifier ResponseClassifier { get; set; } - - /// - /// Gets or sets the value indicating if response would be buffered as part of the pipeline. Defaults to true. - /// - public bool BufferResponse { get; set; } - - /// - /// Gets or sets the network timeout value for this message. If null the value provided in would be used instead. - /// Defaults to null. - /// - public TimeSpan? NetworkTimeout { get; set; } + public new ResponseClassifier ResponseClassifier + { + get => (ResponseClassifier)base.ResponseClassifier; + set => base.ResponseClassifier = value; + } internal int RetryNumber { get; set; } internal DateTimeOffset ProcessingStartTime { get; set; } + internal void SetCancellationToken(CancellationToken cancellationToken) + => CancellationToken = cancellationToken; + /// /// The processing context for the message. /// public MessageProcessingContext ProcessingContext => new(this); - internal void ApplyRequestContext(RequestContext? context, ResponseClassifier? classifier) + internal void ApplyRequestContext(RequestContext context, ResponseClassifier? classifier) { - if (context == null) - { - return; - } - context.Freeze(); + // Azure-specific extensibility piece if (context.Policies?.Count > 0) { Policies ??= new(context.Policies.Count); @@ -111,10 +96,13 @@ internal void ApplyRequestContext(RequestContext? context, ResponseClassifier? c { ResponseClassifier = context.Apply(classifier); } + + Apply(context); } internal List<(HttpPipelinePosition Position, HttpPipelinePolicy Policy)>? Policies { get; set; } + #region Message Properties /// /// Gets a property that modifies the pipeline behavior. Please refer to individual policies documentation on what properties it supports. /// @@ -124,7 +112,7 @@ internal void ApplyRequestContext(RequestContext? context, ResponseClassifier? c public bool TryGetProperty(string name, out object? value) { value = null; - if (_propertyBag.IsEmpty || !_propertyBag.TryGetValue((ulong)typeof(MessagePropertyKey).TypeHandle.Value, out var rawValue)) + if (!TryGetProperty(typeof(MessagePropertyKey), out var rawValue)) { return false; } @@ -140,10 +128,10 @@ public bool TryGetProperty(string name, out object? value) public void SetProperty(string name, object value) { Dictionary properties; - if (!_propertyBag.TryGetValue((ulong)typeof(MessagePropertyKey).TypeHandle.Value, out var rawValue)) + if (!TryGetProperty(typeof(MessagePropertyKey), out var rawValue)) { properties = new Dictionary(); - _propertyBag.Set((ulong)typeof(MessagePropertyKey).TypeHandle.Value, properties); + SetProperty(typeof(MessagePropertyKey), properties); } else { @@ -153,63 +141,39 @@ public void SetProperty(string name, object value) } /// - /// Gets a property that is stored with this instance and can be used for modifying pipeline behavior. + /// Exists as a private key entry into the property bag for stashing string keyed entries in the Type keyed dictionary. /// - /// The property type. - /// The property value. - /// - /// The key value is of type Type for a couple of reasons. Primarily, it allows values to be stored such that though the accessor methods - /// are public, storing values keyed by internal types make them inaccessible to other assemblies. This protects internal values from being overwritten - /// by external code. See the and types for an example of this usage. Secondly, Type - /// comparisons are faster than string comparisons. - /// - /// true if property exists, otherwise. false. - public bool TryGetProperty(Type type, out object? value) => - _propertyBag.TryGetValue((ulong)type.TypeHandle.Value, out value); - - /// - /// Sets a property that is stored with this instance and can be used for modifying pipeline behavior. - /// Internal properties can be keyed with internal types to prevent external code from overwriting these values. - /// - /// The key for the value. - /// The property value. - public void SetProperty(Type type, object value) => - _propertyBag.Set((ulong)type.TypeHandle.Value, value); + private class MessagePropertyKey { } + #endregion /// - /// Returns the response content stream and releases it ownership to the caller. After calling this methods using or would result in exception. + /// Returns the response content stream and releases it ownership to the caller. + /// + /// After calling this method, any attempt to use the + /// or + /// properties on will result in an exception being thrown. /// - /// The content stream or null if response didn't have any. + /// The content stream, or null if + /// did not have content set. public Stream? ExtractResponseContent() { - switch (_response?.ContentStream) + if (!HasResponse) + { + return null; + } + + switch (Response.ContentStream) { case ResponseShouldNotBeUsedStream responseContent: return responseContent.Original; case Stream stream: - _response.ContentStream = new ResponseShouldNotBeUsedStream(_response.ContentStream); + Response.ContentStream = new ResponseShouldNotBeUsedStream(Response.ContentStream); return stream; default: return null; } } - /// - /// Disposes the request and response. - /// - public void Dispose() - { - Request.Dispose(); - _propertyBag.Dispose(); - - var response = _response; - if (response != null) - { - _response = null; - response.Dispose(); - } - } - private class ResponseShouldNotBeUsedStream : Stream { public Stream Original { get; } @@ -260,10 +224,5 @@ public override long Position set => throw CreateException(); } } - - /// - /// Exists as a private key entry into the dictionary for stashing string keyed entries in the Type keyed dictionary. - /// - private class MessagePropertyKey { } } } diff --git a/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs b/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs new file mode 100644 index 000000000000..8b8b96ccb407 --- /dev/null +++ b/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel.Primitives; +using System.Collections; +using System.Collections.Generic; + +namespace Azure.Core.Pipeline +{ + internal struct AzureCorePipelineProcessor : IReadOnlyList + { + private readonly ReadOnlyMemory _policies; + private PolicyEnumerator? _enumerator; + + public AzureCorePipelineProcessor(ReadOnlyMemory policies) + => _policies = policies; + + public ReadOnlyMemory Policies + => _policies; + + public PipelinePolicy this[int index] => _policies.Span[index]; + + public int Count => _policies.Length; + + public IEnumerator GetEnumerator() + => _enumerator ??= new(this); + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + private class PolicyEnumerator : IEnumerator + { + private readonly IReadOnlyList _policies; + private int _current; + + public PolicyEnumerator(IReadOnlyList policies) + { + _policies = policies; + _current = -1; + } + + public PipelinePolicy Current + { + get + { + if (_current >= 0 && _current < _policies.Count) + { + return _policies[_current]; + } + + return null!; + } + } + + object IEnumerator.Current => Current; + + public bool MoveNext() => ++_current < _policies.Count; + + public void Reset() => _current = -1; + + public void Dispose() { } + } + } +} diff --git a/sdk/core/Azure.Core/src/NullableResponseOfT.cs b/sdk/core/Azure.Core/src/NullableResponseOfT.cs index d14cd7ac07ee..459f94897fba 100644 --- a/sdk/core/Azure.Core/src/NullableResponseOfT.cs +++ b/sdk/core/Azure.Core/src/NullableResponseOfT.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System.ClientModel; using System.ComponentModel; namespace Azure @@ -10,26 +11,57 @@ namespace Azure /// /// The type of returned value. #pragma warning disable SA1649 // File name should match first type name - public abstract class NullableResponse + public abstract class NullableResponse : ClientResult #pragma warning restore SA1649 // File name should match first type name { + private readonly T? _value; + private const string NoValue = ""; + internal static Response DefaultResponse = new Response.AzureCoreDefaultResponse(); + + /// + /// TBD. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected NullableResponse() : base(default, DefaultResponse) + { + // Added for back-compat with GA APIs. Any type that derives from + // Response must provide an implementation for GetRawResponse that + // replaces DefaultResponse with the Response populated on HttpMessage + // during the call to pipeline.Send. + + _value = default; + } /// - /// Gets a value indicating whether the current instance has a valid value of its underlying type. + /// TBD. /// - public abstract bool HasValue { get; } + /// + /// + protected NullableResponse(T? value, Response response) + : base(value,ReplaceWithDefaultIfNull(response)) + { + _value = value; + } + + ///// + ///// Gets the value returned by the service. Accessing this property will throw if is false. + ///// + //public virtual T? Value => _value; /// - /// Gets the value returned by the service. Accessing this property will throw if is false. + /// Gets a value indicating whether the current instance has a non-null value. /// - public abstract T? Value { get; } + public virtual bool HasValue => _value != null; + + private static Response ReplaceWithDefaultIfNull(Response? response) + => response ?? DefaultResponse; /// /// Returns the HTTP response returned by the service. /// /// The HTTP response returned by the service. - public abstract Response GetRawResponse(); + public new virtual Response GetRawResponse() => (Response)base.GetRawResponse(); /// [EditorBrowsable(EditorBrowsableState.Never)] @@ -40,6 +72,7 @@ public abstract class NullableResponse public override int GetHashCode() => base.GetHashCode(); /// - public override string ToString() => $"Status: {GetRawResponse()?.Status}, Value: {(HasValue ? Value : NoValue)}"; + public override string ToString() + => $"Status: {GetRawResponse()?.Status}, Value: {(HasValue ? Value : NoValue)}"; } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs new file mode 100644 index 000000000000..9028253d50e8 --- /dev/null +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel.Primitives; +using System.Net.Http; + +namespace Azure.Core.Pipeline +{ + public partial class HttpClientTransport + { + private class AzureCoreHttpPipelineTransport : HttpClientPipelineTransport + { + public AzureCoreHttpPipelineTransport(HttpClient client) : base(client) + { + } + + protected override PipelineMessage CreateMessageCore() + { + PipelineMessage message = base.CreateMessageCore(); + HttpClientTransportRequest request = new(message.Request); + return new HttpMessage(request, ResponseClassifier.Shared); + } + + /// + protected override void OnSendingRequest(PipelineMessage message, HttpRequestMessage httpRequest) + { + if (message is not HttpMessage httpMessage) + { + throw new InvalidOperationException($"Unsupported message type: '{message?.GetType()}'."); + } + + HttpClientTransportRequest.AddAzureProperties(httpMessage, httpRequest); + + httpMessage.ClearResponse(); + } + + /// + protected override void OnReceivedResponse(PipelineMessage message, HttpResponseMessage httpResponse) + { + if (message is not HttpMessage httpMessage) + { + throw new InvalidOperationException($"Unsupported message type: '{message?.GetType()}'."); + } + + if (message.Response is not PipelineResponse pipelineResponse) + { + throw new InvalidOperationException($"Unsupported response type: '{message?.GetType()}'."); + } + + string clientRequestId = httpMessage.Request.ClientRequestId; + httpMessage.Response = new HttpClientTransportResponse(clientRequestId, pipelineResponse); + } + } + } +} diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs new file mode 100644 index 000000000000..9065921ce83c --- /dev/null +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs @@ -0,0 +1,149 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Net.Http; +using System.Runtime.InteropServices; + +namespace Azure.Core.Pipeline +{ + /// + /// An implementation that uses as the transport. + /// + public partial class HttpClientTransport : HttpPipelineTransport, IDisposable + { + private sealed class HttpClientTransportRequest : Request + { + // In this implementation of the abstract Azure.Core.Request type, + // we have two fields for each of the public properties -- one on the + // Request implementation and one in the PipelineRequest implementation. + // The implication of this is that we need to keep both sets of fields + // in sync with each other when they are set from either property on + // Request or PipelineRequest. + + private readonly PipelineRequest _pipelineRequest; + + public HttpClientTransportRequest(PipelineRequest request) + { + _pipelineRequest = request; + + // Initialize duplicated properties on base type from adapted request. + base.SetMethodCore(request.Method); + + // Uri and Content are initialized to null in constructor + // so don't need to be set here. + } + + #region Adapt PipelineResponse to inherit functional implementation from ClientModel + + protected override string GetMethodCore() + => _pipelineRequest.Method; + + protected override void SetMethodCore(string method) + { + // Update fields on both Request and PipelineRequest. + base.SetMethodCore(method); + _pipelineRequest.Method = method; + } + + protected override Uri GetUriCore() + { + Uri uri = Uri.ToUri(); + + // Lazily update the value on the adapted PipelineRequest. + SetUriCore(uri); + + return uri; + } + + protected override void SetUriCore(Uri uri) + { + // Update fields on both Request and PipelineRequest. + base.SetUriCore(uri); + _pipelineRequest.Uri = uri; + } + + protected override BinaryContent? GetContentCore() + => _pipelineRequest.Content; + + protected override void SetContentCore(BinaryContent? content) + { + // Update Content fields on both Request and PipelineRequest. + base.SetContentCore(content); + _pipelineRequest.Content = content; + } + + protected override PipelineRequestHeaders GetHeadersCore() + => _pipelineRequest.Headers; + + #endregion + + #region Implement Azure.Core Request abstract methods + + protected internal override void AddHeader(string name, string value) + => _pipelineRequest.Headers.Add(name, value); + + protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) + => _pipelineRequest.Headers.TryGetValue(name, out value); + + protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) + => _pipelineRequest.Headers.TryGetValues(name, out values); + + protected internal override bool ContainsHeader(string name) + => _pipelineRequest.Headers.TryGetValue(name, out _); + + protected internal override bool RemoveHeader(string name) + => _pipelineRequest.Headers.Remove(name); + + protected internal override IEnumerable EnumerateHeaders() + { + foreach (KeyValuePair header in _pipelineRequest.Headers) + { + yield return new HttpHeader(header.Key, header.Value); + } + } + + #endregion + + #region Azure.Core extensions of ClientModel functionality + + private const string MessageForServerCertificateCallback = "MessageForServerCertificateCallback"; + + internal static void AddAzureProperties(HttpMessage message, HttpRequestMessage httpRequest) + { + SetPropertiesOrOptions(httpRequest, MessageForServerCertificateCallback, message); + + AddPropertiesForBlazor(httpRequest); + } + + private static void AddPropertiesForBlazor(HttpRequestMessage currentRequest) + { + // Disable response caching and enable streaming in Blazor apps + // see https://github.com/dotnet/aspnetcore/blob/3143d9550014006080bb0def5b5c96608b025a13/src/Components/WebAssembly/WebAssembly/src/Http/WebAssemblyHttpRequestMessageExtensions.cs + if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))) + { + SetPropertiesOrOptions(currentRequest, "WebAssemblyFetchOptions", new Dictionary { { "cache", "no-store" } }); + SetPropertiesOrOptions(currentRequest, "WebAssemblyEnableStreamingResponse", true); + } + } + + private static void SetPropertiesOrOptions(HttpRequestMessage httpRequest, string name, T value) + { +#if NET5_0_OR_GREATER + httpRequest.Options.Set(new HttpRequestOptionsKey(name), value); +#else + httpRequest.Properties[name] = value; +#endif + } + + #endregion + + public override void Dispose() + => _pipelineRequest.Dispose(); + } + } +} diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs new file mode 100644 index 000000000000..604df526b3e3 --- /dev/null +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.ClientModel.Primitives; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Net.Http; + +namespace Azure.Core.Pipeline +{ + /// + /// An implementation that uses as the transport. + /// + public partial class HttpClientTransport : HttpPipelineTransport + { + private sealed class HttpClientTransportResponse : Response + { + private string _clientRequestId; + private readonly PipelineResponse _pipelineResponse; + + public HttpClientTransportResponse(string clientRequestId, PipelineResponse pipelineResponse) + { + _clientRequestId = clientRequestId; + _pipelineResponse = pipelineResponse; + } + + public override int Status => _pipelineResponse.Status; + + public override string ReasonPhrase => _pipelineResponse.ReasonPhrase; + + public override string ClientRequestId + { + get => _clientRequestId; + set => _clientRequestId = value; + } + + public override Stream? ContentStream + { + get => _pipelineResponse.ContentStream; + set => _pipelineResponse.ContentStream = value; + } + + protected internal override bool ContainsHeader(string name) + => _pipelineResponse.Headers.TryGetValue(name, out _); + + protected internal override IEnumerable EnumerateHeaders() + { + foreach (KeyValuePair header in _pipelineResponse.Headers) + { + yield return new HttpHeader(header.Key, header.Value); + } + } + + protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) + => _pipelineResponse.Headers.TryGetValue(name, out value); + + protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) + => _pipelineResponse.Headers.TryGetValues(name, out values); + + public override void Dispose() + { + PipelineResponse response = _pipelineResponse; + response?.Dispose(); + } + } + } +} diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs index 9a8dd8b8c2df..c92620d445a8 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs @@ -2,15 +2,11 @@ // Licensed under the MIT License. using System; -using System.Buffers; -using System.Collections.Generic; +using System.ClientModel; +using System.ClientModel.Primitives; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; using System.Net; using System.Net.Http; -using System.Net.Http.Headers; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Threading; @@ -21,33 +17,32 @@ namespace Azure.Core.Pipeline /// /// An implementation that uses as the transport. /// - public class HttpClientTransport : HttpPipelineTransport, IDisposable + public partial class HttpClientTransport : HttpPipelineTransport, IDisposable { - internal const string MessageForServerCertificateCallback = "MessageForServerCertificateCallback"; + /// + /// A shared instance of with default parameters. + /// + public static readonly HttpClientTransport Shared = new HttpClientTransport(); - // Internal for testing + // The transport's private HttpClient has been made internal because it is used by tests. + // TODO: move these tests into System.Rest? - can we make it private when we do? internal HttpClient Client { get; } - /// - /// Creates a new instance using default configuration. - /// - public HttpClientTransport() : this(CreateDefaultClient()) - { } + private readonly AzureCoreHttpPipelineTransport _transport; /// /// Creates a new instance using default configuration. /// - /// The that to configure the behavior of the transport. - internal HttpClientTransport(HttpPipelineTransportOptions? options = null) : this(CreateDefaultClient(options)) - { } + public HttpClientTransport() : this(CreateDefaultClient()) + { + } /// /// Creates a new instance of using the provided client instance. /// /// The instance of to use. - public HttpClientTransport(HttpMessageHandler messageHandler) + public HttpClientTransport(HttpMessageHandler messageHandler) : this(new HttpClient(messageHandler)) { - Client = new HttpClient(messageHandler) ?? throw new ArgumentNullException(nameof(messageHandler)); } /// @@ -57,92 +52,61 @@ public HttpClientTransport(HttpMessageHandler messageHandler) public HttpClientTransport(HttpClient client) { Client = client ?? throw new ArgumentNullException(nameof(client)); + + _transport = new AzureCoreHttpPipelineTransport(client); } /// - /// A shared instance of with default parameters. + /// Creates a new instance using default configuration. /// - public static readonly HttpClientTransport Shared = new HttpClientTransport(); + /// The that to configure the behavior of the transport. + internal HttpClientTransport(HttpPipelineTransportOptions? options = null) + : this(CreateDefaultClient(options)) + { + } /// public sealed override Request CreateRequest() - => new PipelineRequest(); + => ((HttpMessage)_transport.CreateMessage()).Request; /// public override void Process(HttpMessage message) { -#if NET5_0_OR_GREATER - ProcessAsync(message, false).EnsureCompleted(); -#else - // Intentionally blocking here -#pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult(). - ProcessAsync(message).AsTask().GetAwaiter().GetResult(); -#pragma warning restore AZC0102 // Do not use GetAwaiter().GetResult(). -#endif - } - - /// - public override ValueTask ProcessAsync(HttpMessage message) => ProcessAsync(message, true); - -#pragma warning disable CA1801 // async parameter unused on netstandard - private async ValueTask ProcessAsync(HttpMessage message, bool async) -#pragma warning restore CA1801 - { - using HttpRequestMessage httpRequest = BuildRequestMessage(message); - SetPropertiesOrOptions(httpRequest, MessageForServerCertificateCallback, message); - HttpResponseMessage responseMessage; - Stream? contentStream = null; - message.ClearResponse(); try { -#if NET5_0_OR_GREATER - if (!async) + _transport.Process(message); + } + catch (ClientResultException e) + { + if (message.HasResponse) { - // Sync HttpClient.Send is not supported on browser but neither is the sync-over-async - // HttpClient.Send would throw a NotSupported exception instead of GetAwaiter().GetResult() - // throwing a System.Threading.SynchronizationLockException: Cannot wait on monitors on this runtime. -#pragma warning disable CA1416 // 'HttpClient.Send(HttpRequestMessage, HttpCompletionOption, CancellationToken)' is unsupported on 'browser' - responseMessage = Client.Send(httpRequest, HttpCompletionOption.ResponseHeadersRead, message.CancellationToken); -#pragma warning restore CA1416 + throw new RequestFailedException(message.Response, e.InnerException); } else -#endif - { -#pragma warning disable AZC0110 // DO NOT use await keyword in possibly synchronous scope. - responseMessage = await Client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, message.CancellationToken) -#pragma warning restore AZC0110 // DO NOT use await keyword in possibly synchronous scope. - .ConfigureAwait(false); - } - - if (responseMessage.Content != null) { -#if NET5_0_OR_GREATER - if (async) - { - contentStream = await responseMessage.Content.ReadAsStreamAsync(message.CancellationToken).ConfigureAwait(false); - } - else - { - contentStream = responseMessage.Content.ReadAsStream(message.CancellationToken); - } -#else -#pragma warning disable AZC0110 // DO NOT use await keyword in possibly synchronous scope. - contentStream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false); -#pragma warning restore AZC0110 // DO NOT use await keyword in possibly synchronous scope. -#endif + throw new RequestFailedException(e.Message, e.InnerException); } } - // HttpClient on NET5 throws OperationCanceledException from sync call sites, normalize to TaskCanceledException - catch (OperationCanceledException e) when (CancellationHelper.ShouldWrapInOperationCanceledException(e, message.CancellationToken)) + } + + /// + public override async ValueTask ProcessAsync(HttpMessage message) + { + try { - throw CancellationHelper.CreateOperationCanceledException(e, message.CancellationToken); + await _transport.ProcessAsync(message).ConfigureAwait(false); } - catch (HttpRequestException e) + catch (ClientResultException e) { - throw new RequestFailedException(e.Message, e); + if (message.HasResponse) + { + throw new RequestFailedException(message.Response, e.InnerException); + } + else + { + throw new RequestFailedException(e.Message, e.InnerException); + } } - - message.Response = new PipelineResponse(message.Request.ClientRequestId, responseMessage, contentStream); } private static HttpClient CreateDefaultClient(HttpPipelineTransportOptions? options = null) @@ -199,478 +163,6 @@ private static void SetProxySettings(HttpMessageHandler messageHandler) } } - private static HttpRequestMessage BuildRequestMessage(HttpMessage message) - { - if (!(message.Request is PipelineRequest pipelineRequest)) - { - throw new InvalidOperationException("the request is not compatible with the transport"); - } - return pipelineRequest.BuildRequestMessage(message.CancellationToken); - } - - internal static bool TryGetHeader(HttpHeaders headers, HttpContent? content, string name, [NotNullWhen(true)] out string? value) - { -#if NET6_0_OR_GREATER - if (headers.NonValidated.TryGetValues(name, out HeaderStringValues values) || - content is not null && content.Headers.NonValidated.TryGetValues(name, out values)) - { - value = JoinHeaderValues(values); - return true; - } -#else - if (TryGetHeader(headers, content, name, out IEnumerable? values)) - { - value = JoinHeaderValues(values); - return true; - } -#endif - value = null; - return false; - } - - internal static bool TryGetHeader(HttpHeaders headers, HttpContent? content, string name, [NotNullWhen(true)] out IEnumerable? values) - { -#if NET6_0_OR_GREATER - if (headers.NonValidated.TryGetValues(name, out HeaderStringValues headerStringValues) || - content != null && - content.Headers.NonValidated.TryGetValues(name, out headerStringValues)) - { - values = headerStringValues; - return true; - } - - values = null; - return false; -#else - return headers.TryGetValues(name, out values) || - content != null && - content.Headers.TryGetValues(name, out values); -#endif - - } - - internal static IEnumerable GetHeaders(HttpHeaders headers, HttpContent? content) - { -#if NET6_0_OR_GREATER - foreach (var (key, value) in headers.NonValidated) - { - yield return new HttpHeader(key, JoinHeaderValues(value)); - } - - if (content is not null) - { - foreach (var (key, value) in content.Headers.NonValidated) - { - yield return new HttpHeader(key, JoinHeaderValues(value)); - } - } -#else - foreach (KeyValuePair> header in headers) - { - yield return new HttpHeader(header.Key, JoinHeaderValues(header.Value)); - } - - if (content != null) - { - foreach (KeyValuePair> header in content.Headers) - { - yield return new HttpHeader(header.Key, JoinHeaderValues(header.Value)); - } - } -#endif - - } - - internal static bool RemoveHeader(HttpHeaders headers, HttpContent? content, string name) - { - // .Remove throws on invalid header name so use TryGet here to check -#if NET6_0_OR_GREATER - if (headers.NonValidated.Contains(name) && headers.Remove(name)) - { - return true; - } - - return content is not null && content.Headers.NonValidated.Contains(name) && content.Headers.Remove(name); -#else - if (headers.TryGetValues(name, out _) && headers.Remove(name)) - { - return true; - } - - return content?.Headers.TryGetValues(name, out _) == true && content.Headers.Remove(name); -#endif - } - - internal static bool ContainsHeader(HttpHeaders headers, HttpContent? content, string name) - { - // .Contains throws on invalid header name so use TryGet here -#if NET6_0_OR_GREATER - return headers.NonValidated.Contains(name) || content is not null && content.Headers.NonValidated.Contains(name); -#else - if (headers.TryGetValues(name, out _)) - { - return true; - } - - return content?.Headers.TryGetValues(name, out _) == true; -#endif - } - -#if NET6_0_OR_GREATER - private static string JoinHeaderValues(HeaderStringValues values) - { - var count = values.Count; - if (count == 0) - { - return string.Empty; - } - - // Special case when HeaderStringValues.Count == 1, because HttpHeaders also special cases it and creates HeaderStringValues instance from a single string - // https://github.com/dotnet/runtime/blob/ef5e27eacecf34a36d72a8feb9082f408779675a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeadersNonValidated.cs#L150 - // https://github.com/dotnet/runtime/blob/ef5e27eacecf34a36d72a8feb9082f408779675a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs#L1105 - // Which is later used in HeaderStringValues.ToString: - // https://github.com/dotnet/runtime/blob/729bf92e6e2f91aa337da9459bef079b14a0bf34/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderStringValues.cs#L47 - if (count == 1) - { - return values.ToString(); - } - - // While HeaderStringValueToStringVsEnumerator performance test shows that `HeaderStringValues.ToString` is faster than DefaultInterpolatedStringHandler, - // we can't use it here because it uses ", " as default separator and doesn't allow customization. - var interpolatedStringHandler = new DefaultInterpolatedStringHandler(count-1, count); - var isFirst = true; - foreach (var str in values) - { - if (isFirst) - { - isFirst = false; - } - else - { - interpolatedStringHandler.AppendLiteral(","); - } - interpolatedStringHandler.AppendFormatted(str); - } - return string.Create(null, ref interpolatedStringHandler); - } -#else - private static string JoinHeaderValues(IEnumerable values) - { - return string.Join(",", values); - } -#endif - - private sealed class PipelineRequest : Request - { - private string? _clientRequestId; - private ArrayBackedPropertyBag _headers; - - public PipelineRequest() - { - Method = RequestMethod.Get; - _headers = new ArrayBackedPropertyBag(); - } - - public override string ClientRequestId - { - get => _clientRequestId ??= Guid.NewGuid().ToString(); - set - { - Argument.AssertNotNull(value, nameof(value)); - _clientRequestId = value; - } - } - - protected internal override void SetHeader(string name, string value) - { - _headers.Set(new IgnoreCaseString(name), value); - } - - protected internal override void AddHeader(string name, string value) - { - if (_headers.TryAdd(new IgnoreCaseString(name), value, out var existingValue)) - { - return; - } - - switch (existingValue) - { - case string stringValue: - _headers.Set(new IgnoreCaseString(name), new List { stringValue, value }); - break; - case List listValue: - listValue.Add(value); - break; - } - } - - protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) - { - if (_headers.TryGetValue(new IgnoreCaseString(name), out var headerValue)) - { - value = GetHttpHeaderValue(name, headerValue); - return true; - } - - value = default; - return false; - } - - protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) - { - if (_headers.TryGetValue(new IgnoreCaseString(name), out var value)) - { - values = value switch - { - string headerValue => new[]{ headerValue }, - List headerValues => headerValues, - _ => throw new InvalidOperationException($"Unexpected type for header {name}: {value.GetType()}") - }; - return true; - } - - values = default; - return false; - } - - protected internal override bool ContainsHeader(string name) => _headers.TryGetValue(new IgnoreCaseString(name), out _); - - protected internal override bool RemoveHeader(string name) => _headers.TryRemove(new IgnoreCaseString(name)); - - protected internal override IEnumerable EnumerateHeaders() - { - for (int i = 0; i < _headers.Count; i++) - { - _headers.GetAt(i, out var headerName, out var headerValue); - yield return new HttpHeader(headerName, GetHttpHeaderValue(headerName, headerValue)); - } - } - - public HttpRequestMessage BuildRequestMessage(CancellationToken cancellation) - { - var method = ToHttpClientMethod(Method); - var uri = Uri.ToUri(); - var currentRequest = new HttpRequestMessage(method, uri); - var currentContent = Content != null ? new PipelineContentAdapter(Content, cancellation) : null; - currentRequest.Content = currentContent; -#if NETFRAMEWORK - currentRequest.Headers.ExpectContinue = false; -#endif - for (int i = 0; i < _headers.Count; i++) - { - _headers.GetAt(i, out var headerName, out var value); - switch (value) - { - case string stringValue: - // Authorization is special cased because it is in the hot path for auth polices that set this header on each request and retry. - if (headerName == HttpHeader.Names.Authorization && AuthenticationHeaderValue.TryParse(stringValue, out var authHeader)) - { - currentRequest.Headers.Authorization = authHeader; - } - else if (!currentRequest.Headers.TryAddWithoutValidation(headerName, stringValue)) - { - if (currentContent != null && !currentContent.Headers.TryAddWithoutValidation(headerName, stringValue)) - { - throw new InvalidOperationException($"Unable to add header {headerName} to header collection."); - } - } - break; - case List listValue: - if (!currentRequest.Headers.TryAddWithoutValidation(headerName, listValue)) - { - if (currentContent != null && !currentContent.Headers.TryAddWithoutValidation(headerName, listValue)) - { - throw new InvalidOperationException($"Unable to add header {headerName} to header collection."); - } - } - break; - } - } - - AddPropertiesForBlazor(currentRequest); - - return currentRequest; - } - - private static void AddPropertiesForBlazor(HttpRequestMessage currentRequest) - { - // Disable response caching and enable streaming in Blazor apps - // see https://github.com/dotnet/aspnetcore/blob/3143d9550014006080bb0def5b5c96608b025a13/src/Components/WebAssembly/WebAssembly/src/Http/WebAssemblyHttpRequestMessageExtensions.cs - if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"))) - { - SetPropertiesOrOptions(currentRequest, "WebAssemblyFetchOptions", new Dictionary { { "cache", "no-store" } }); - SetPropertiesOrOptions(currentRequest, "WebAssemblyEnableStreamingResponse", true); - } - } - - private static string GetHttpHeaderValue(string headerName, object value) => value switch - { - string headerValue => headerValue, - List headerValues => string.Join(",", headerValues), - _ => throw new InvalidOperationException($"Unexpected type for header {headerName}: {value?.GetType()}") - }; - - public override void Dispose() - { - _headers.Dispose(); - var content = Content; - if (content != null) - { - Content = null; - content.Dispose(); - } - } - - public override string ToString() => BuildRequestMessage(default).ToString(); - - private static readonly HttpMethod s_patch = new HttpMethod("PATCH"); - - private static HttpMethod ToHttpClientMethod(RequestMethod requestMethod) - { - var method = requestMethod.Method; - - // Fast-path common values - if (method.Length == 3) - { - if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase)) - { - return HttpMethod.Get; - } - - if (string.Equals(method, "PUT", StringComparison.OrdinalIgnoreCase)) - { - return HttpMethod.Put; - } - } - else if (method.Length == 4) - { - if (string.Equals(method, "POST", StringComparison.OrdinalIgnoreCase)) - { - return HttpMethod.Post; - } - if (string.Equals(method, "HEAD", StringComparison.OrdinalIgnoreCase)) - { - return HttpMethod.Head; - } - } - else - { - if (string.Equals(method, "PATCH", StringComparison.OrdinalIgnoreCase)) - { - return s_patch; - } - if (string.Equals(method, "DELETE", StringComparison.OrdinalIgnoreCase)) - { - return HttpMethod.Delete; - } - } - - return new HttpMethod(method); - } - - private readonly struct IgnoreCaseString : IEquatable - { - private readonly string _value; - - public IgnoreCaseString(string value) - { - _value = value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(IgnoreCaseString other) => string.Equals(_value, other._value, StringComparison.OrdinalIgnoreCase); - public override bool Equals(object? obj) => obj is IgnoreCaseString other && Equals(other); - public override int GetHashCode() => _value.GetHashCode(); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(IgnoreCaseString left, IgnoreCaseString right) => left.Equals(right); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(IgnoreCaseString left, IgnoreCaseString right) => !left.Equals(right); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator string(IgnoreCaseString ics) => ics._value; - } - - private sealed class PipelineContentAdapter : HttpContent - { - private readonly RequestContent _pipelineContent; - private readonly CancellationToken _cancellationToken; - - public PipelineContentAdapter(RequestContent pipelineContent, CancellationToken cancellationToken) - { - _pipelineContent = pipelineContent; - _cancellationToken = cancellationToken; - } - - protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context) => await _pipelineContent.WriteToAsync(stream, _cancellationToken).ConfigureAwait(false); - - protected override bool TryComputeLength(out long length) => _pipelineContent.TryComputeLength(out length); - -#if NET5_0_OR_GREATER - protected override async Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) - { - await _pipelineContent!.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); - } - - protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken) - { - _pipelineContent.WriteTo(stream, cancellationToken); - } -#endif - } - } - - private sealed class PipelineResponse : Response - { - private readonly HttpResponseMessage _responseMessage; - - private readonly HttpContent _responseContent; - -#pragma warning disable CA2213 // Content stream is intentionally not disposed - private Stream? _contentStream; -#pragma warning restore CA2213 - - public PipelineResponse(string requestId, HttpResponseMessage responseMessage, Stream? contentStream) - { - ClientRequestId = requestId ?? throw new ArgumentNullException(nameof(requestId)); - _responseMessage = responseMessage ?? throw new ArgumentNullException(nameof(responseMessage)); - _contentStream = contentStream; - _responseContent = _responseMessage.Content; - } - - public override int Status => (int)_responseMessage.StatusCode; - - public override string ReasonPhrase => _responseMessage.ReasonPhrase ?? string.Empty; - - public override Stream? ContentStream - { - get => _contentStream; - set - { - // Make sure we don't dispose the content if the stream was replaced - _responseMessage.Content = null; - - _contentStream = value; - } - } - - public override string ClientRequestId { get; set; } - - protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) => HttpClientTransport.TryGetHeader(_responseMessage.Headers, _responseContent, name, out value); - - protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) => HttpClientTransport.TryGetHeader(_responseMessage.Headers, _responseContent, name, out values); - - protected internal override bool ContainsHeader(string name) => HttpClientTransport.ContainsHeader(_responseMessage.Headers, _responseContent, name); - - protected internal override IEnumerable EnumerateHeaders() => GetHeaders(_responseMessage.Headers, _responseContent); - - public override void Dispose() - { - _responseMessage?.Dispose(); - DisposeStreamIfNotBuffered(ref _contentStream); - } - - public override string ToString() => _responseMessage.ToString(); - } #if NETCOREAPP private static SocketsHttpHandler ApplyOptionsToHandler(SocketsHttpHandler httpHandler, HttpPipelineTransportOptions? options) { @@ -691,11 +183,11 @@ private static SocketsHttpHandler ApplyOptionsToHandler(SocketsHttpHandler httpH sslPolicyErrors)); } // Set ClientCertificates - foreach (var cert in options.ClientCertificates) + foreach (var cert in options.ClientCertificates) { - httpHandler.SslOptions ??= new System.Net.Security.SslClientAuthenticationOptions(); - httpHandler.SslOptions.ClientCertificates ??= new X509CertificateCollection(); - httpHandler.SslOptions.ClientCertificates!.Add(cert); + httpHandler.SslOptions ??= new System.Net.Security.SslClientAuthenticationOptions(); + httpHandler.SslOptions.ClientCertificates ??= new X509CertificateCollection(); + httpHandler.SslOptions.ClientCertificates!.Add(cert); } #pragma warning restore CA1416 // 'X509Certificate2' is unsupported on 'browser' return httpHandler; @@ -720,11 +212,16 @@ private static HttpClientHandler ApplyOptionsToHandler(HttpClientHandler httpHan // Set ClientCertificates foreach (var cert in options.ClientCertificates) { - httpHandler.ClientCertificates.Add(cert); + httpHandler.ClientCertificates.Add(cert); } return httpHandler; } #endif + + private static bool UseCookies() => AppContextSwitchHelper.GetConfigValue( + "Azure.Core.Pipeline.HttpClientTransport.EnableCookies", + "AZURE_CORE_HTTPCLIENT_ENABLE_COOKIES"); + /// /// Disposes the underlying . /// @@ -734,20 +231,8 @@ public void Dispose() { Client.Dispose(); } - GC.SuppressFinalize(this); - } - private static void SetPropertiesOrOptions(HttpRequestMessage httpRequest, string name, T value) - { -#if NET5_0_OR_GREATER - httpRequest.Options.Set(new HttpRequestOptionsKey(name), value); -#else - httpRequest.Properties[name] = value; -#endif + GC.SuppressFinalize(this); } - - private static bool UseCookies() => AppContextSwitchHelper.GetConfigValue( - "Azure.Core.Pipeline.HttpClientTransport.EnableCookies", - "AZURE_CORE_HTTPCLIENT_ENABLE_COOKIES"); } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs index 68c04b46499a..04c1a25871fa 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs @@ -92,15 +92,14 @@ public Request CreateRequest() /// /// The message. public HttpMessage CreateMessage() - { - return new HttpMessage(CreateRequest(), ResponseClassifier); - } + => new(CreateRequest(), ResponseClassifier); /// /// /// /// - public HttpMessage CreateMessage(RequestContext? context) => CreateMessage(context, default); + public HttpMessage CreateMessage(RequestContext? context) + => CreateMessage(context, default); /// /// Creates a new instance. @@ -110,12 +109,13 @@ public HttpMessage CreateMessage() /// The message. public HttpMessage CreateMessage(RequestContext? context, ResponseClassifier? classifier = default) { - var message = CreateMessage(); - if (classifier != null) + HttpMessage message = new HttpMessage(CreateRequest(), classifier ?? ResponseClassifier); + + if (context != null) { - message.ResponseClassifier = classifier; + message.ApplyRequestContext(context, classifier); } - message.ApplyRequestContext(context, classifier); + return message; } @@ -132,7 +132,7 @@ public HttpMessage CreateMessage(RequestContext? context, ResponseClassifier? cl /// The representing the asynchronous operation. public ValueTask SendAsync(HttpMessage message, CancellationToken cancellationToken) { - message.CancellationToken = cancellationToken; + message.SetCancellationToken(cancellationToken); message.ProcessingStartTime = DateTimeOffset.UtcNow; AddHttpMessageProperties(message); @@ -146,11 +146,12 @@ public ValueTask SendAsync(HttpMessage message, CancellationToken cancellationTo private async ValueTask SendAsync(HttpMessage message) { - var length = _pipeline.Length + message.Policies!.Count; - var policies = ArrayPool.Shared.Rent(length); + int length = _pipeline.Length + message.Policies!.Count; + HttpPipelinePolicy[] policies = ArrayPool.Shared.Rent(length); + try { - var pipeline = CreateRequestPipeline(policies, message.Policies); + ReadOnlyMemory pipeline = CreateRequestPipeline(policies, message.Policies); await pipeline.Span[0].ProcessAsync(message, pipeline.Slice(1)).ConfigureAwait(false); } finally @@ -166,27 +167,32 @@ private async ValueTask SendAsync(HttpMessage message) /// The to use. public void Send(HttpMessage message, CancellationToken cancellationToken) { - message.CancellationToken = cancellationToken; + message.SetCancellationToken(cancellationToken); message.ProcessingStartTime = DateTimeOffset.UtcNow; AddHttpMessageProperties(message); if (message.Policies == null || message.Policies.Count == 0) { _pipeline.Span[0].Process(message, _pipeline.Slice(1)); + return; } - else + + Send(message); + } + + private void Send(HttpMessage message) + { + int length = _pipeline.Length + message.Policies!.Count; + HttpPipelinePolicy[] policies = ArrayPool.Shared.Rent(length); + + try { - var length = _pipeline.Length + message.Policies.Count; - var policies = ArrayPool.Shared.Rent(length); - try - { - var pipeline = CreateRequestPipeline(policies, message.Policies); - pipeline.Span[0].Process(message, pipeline.Slice(1)); - } - finally - { - ArrayPool.Shared.Return(policies); - } + ReadOnlyMemory pipeline = CreateRequestPipeline(policies, message.Policies); + pipeline.Span[0].Process(message, pipeline.Slice(1)); + } + finally + { + ArrayPool.Shared.Return(policies); } } @@ -258,7 +264,7 @@ private ReadOnlyMemory CreateRequestPipeline(HttpPipelinePol } // Copy over client policies and splice in custom policies at designated indices - var pipeline = _pipeline.Span; + ReadOnlySpan pipeline = _pipeline.Span; int transportIndex = pipeline.Length - 1; pipeline.Slice(0, _perCallIndex).CopyTo(policies); @@ -291,7 +297,7 @@ private static int AddCustomPolicies(List<(HttpPipelinePosition Position, HttpPi int count = 0; if (source != null) { - foreach (var policy in source) + foreach ((HttpPipelinePosition Position, HttpPipelinePolicy Policy) policy in source) { if (policy.Position == position) { @@ -328,7 +334,7 @@ internal HttpMessagePropertiesScope(IDictionary messageProperti if (parent != null) { Properties = new Dictionary(parent.Properties); - foreach (var kvp in messageProperties) + foreach (KeyValuePair kvp in messageProperties) { Properties[kvp.Key] = kvp.Value; } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs index f8b187141b07..e84ee002ae01 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs @@ -102,7 +102,7 @@ internal static (ResponseClassifier Classifier, HttpPipelineTransport Transport, buildOptions.PerCallPolicies.Count + buildOptions.PerRetryPolicies.Count); - void AddCustomerPolicies(HttpPipelinePosition position) + void AddUserPolicies(HttpPipelinePosition position) { if (buildOptions.ClientOptions.Policies != null) { @@ -141,7 +141,7 @@ void AddNonNullPolicies(HttpPipelinePolicy[] policiesToAdd) AddNonNullPolicies(buildOptions.PerCallPolicies.ToArray()); - AddCustomerPolicies(HttpPipelinePosition.PerCall); + AddUserPolicies(HttpPipelinePosition.PerCall); var perCallIndex = policies.Count; @@ -170,7 +170,7 @@ void AddNonNullPolicies(HttpPipelinePolicy[] policiesToAdd) AddNonNullPolicies(buildOptions.PerRetryPolicies.ToArray()); - AddCustomerPolicies(HttpPipelinePosition.PerRetry); + AddUserPolicies(HttpPipelinePosition.PerRetry); var perRetryIndex = policies.Count; @@ -185,7 +185,7 @@ void AddNonNullPolicies(HttpPipelinePolicy[] policiesToAdd) policies.Add(new RequestActivityPolicy(isDistributedTracingEnabled, ClientDiagnostics.GetResourceProviderNamespace(buildOptions.ClientOptions.GetType().Assembly), sanitizer)); - AddCustomerPolicies(HttpPipelinePosition.BeforeTransport); + AddUserPolicies(HttpPipelinePosition.BeforeTransport); // Override the provided Transport with the provided transport options if the transport has not been set after default construction and options are not null. HttpPipelineTransport transport = buildOptions.ClientOptions.Transport; diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs index 1de64f1a73ea..0e5a37ed88e9 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable enable - using System; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.Threading.Tasks; namespace Azure.Core.Pipeline @@ -11,10 +11,10 @@ namespace Azure.Core.Pipeline /// /// Represent an extension point for the that can mutate the and react to received . /// - public abstract class HttpPipelinePolicy + public abstract class HttpPipelinePolicy : PipelinePolicy { /// - /// Applies the policy to the . Implementers are expected to mutate before calling and observe the changes after. + /// Applies the policy to the . Implementers are expected to mutate before calling and observe the changes after. /// /// The this policy would be applied to. /// The set of to execute after current one. @@ -22,7 +22,7 @@ public abstract class HttpPipelinePolicy public abstract ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline); /// - /// Applies the policy to the . Implementers are expected to mutate before calling and observe the changes after. + /// Applies the policy to the . Implementers are expected to mutate and observe the changes after. /// /// The this policy would be applied to. /// The set of to execute after current one. @@ -48,5 +48,53 @@ protected static void ProcessNext(HttpMessage message, ReadOnlyMemory + /// TBD. + /// + /// + /// + /// + /// + /// + public sealed override async ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList pipeline, int currentIndex) + { + if (message is not HttpMessage httpMessage) + { + throw new InvalidOperationException($"Invalid type for message: '{message?.GetType()}'"); + } + + if (pipeline is not AzureCorePipelineProcessor processor) + { + throw new InvalidOperationException($"Invalid type for pipeline: '{pipeline?.GetType()}'"); + } + + // The contract across ClientModel policy and Azure.Core policy is different + // so if we're calling Process from a ClientModel policy, we need to pop some + // policies off the stack before calling Process on the Azure.Core policy. + await ProcessAsync(httpMessage, processor.Policies.Slice(currentIndex + 1)).ConfigureAwait(false); + } + + /// + /// TBD. + /// + /// + /// + /// + /// + public sealed override void Process(PipelineMessage message, IReadOnlyList pipeline, int currentIndex) + { + if (message is not HttpMessage httpMessage) + { + throw new InvalidOperationException($"Invalid type for message: '{message?.GetType()}'"); + } + + if (pipeline is not AzureCorePipelineProcessor processor) + { + throw new InvalidOperationException($"Invalid type for pipeline: '{pipeline?.GetType()}'"); + } + + Process(httpMessage, processor.Policies.Slice(currentIndex + 1)); + } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs index 9a222f88e37a..f3153bbe9011 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs @@ -6,11 +6,8 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; -using System.Linq; using System.Net; -using System.Net.Http; using System.Net.Http.Headers; -using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -50,16 +47,16 @@ internal HttpWebRequestTransport(Action configureRequest) /// public override void Process(HttpMessage message) { - ProcessInternal(message, false).EnsureCompleted(); + ProcessSyncOrAsync(message, false).EnsureCompleted(); } /// public override async ValueTask ProcessAsync(HttpMessage message) { - await ProcessInternal(message, true).ConfigureAwait(false); + await ProcessSyncOrAsync(message, true).ConfigureAwait(false); } - private async ValueTask ProcessInternal(HttpMessage message, bool async) + private async ValueTask ProcessSyncOrAsync(HttpMessage message, bool async) { var request = CreateRequest(message.Request); @@ -107,7 +104,7 @@ private async ValueTask ProcessInternal(HttpMessage message, bool async) webResponse = exception.Response; } - message.Response = new HttpWebResponseImplementation(message.Request.ClientRequestId, (HttpWebResponse)webResponse); + message.Response = new HttpWebTransportResponse(message.Request.ClientRequestId, (HttpWebResponse)webResponse); } // ObjectDisposedException might be thrown if the request is aborted during the content upload via SSL catch (ObjectDisposedException) when (message.CancellationToken.IsCancellationRequested) @@ -262,16 +259,52 @@ private HttpWebRequest CreateRequest(Request messageRequest) /// public override Request CreateRequest() { - return new HttpWebRequestImplementation(); + return new HttpWebTransportRequest(); } - private sealed class HttpWebResponseImplementation : Response + private sealed class HttpWebTransportRequest : Request + { + public HttpWebTransportRequest() + { + Method = RequestMethod.Get; + } + + private readonly DictionaryHeaders _headers = new(); + + protected internal override void SetHeader(string name, string value) => _headers.SetHeader(name, value); + + protected internal override void AddHeader(string name, string value) => _headers.AddHeader(name, value); + + protected internal override bool TryGetHeader(string name, out string value) => _headers.TryGetHeader(name, out value); + + protected internal override bool TryGetHeaderValues(string name, out IEnumerable values) => _headers.TryGetHeaderValues(name, out values); + + protected internal override bool ContainsHeader(string name) => _headers.TryGetHeaderValues(name, out _); + + protected internal override bool RemoveHeader(string name) => _headers.RemoveHeader(name); + + protected internal override IEnumerable EnumerateHeaders() => _headers.EnumerateHeaders(); + + public override RequestContent? Content { get; set; } + + public override void Dispose() + { + var content = Content; + if (content != null) + { + Content = null; + content.Dispose(); + } + } + } + + private sealed class HttpWebTransportResponse : Response { private readonly HttpWebResponse _webResponse; private Stream? _contentStream; private Stream? _originalContentStream; - public HttpWebResponseImplementation(string clientRequestId, HttpWebResponse webResponse) + public HttpWebTransportResponse(string clientRequestId, HttpWebResponse webResponse) { _webResponse = webResponse; _originalContentStream = _webResponse.GetResponseStream(); @@ -332,53 +365,6 @@ protected internal override IEnumerable EnumerateHeaders() } } - private sealed class HttpWebRequestImplementation : Request - { - public HttpWebRequestImplementation() - { - Method = RequestMethod.Get; - } - - private string? _clientRequestId; - private readonly DictionaryHeaders _headers = new(); - - protected internal override void SetHeader(string name, string value) => _headers.SetHeader(name, value); - - protected internal override void AddHeader(string name, string value) => _headers.AddHeader(name, value); - - protected internal override bool TryGetHeader(string name, out string value) => _headers.TryGetHeader(name, out value); - - protected internal override bool TryGetHeaderValues(string name, out IEnumerable values) => _headers.TryGetHeaderValues(name, out values); - - protected internal override bool ContainsHeader(string name) => _headers.TryGetHeaderValues(name, out _); - - protected internal override bool RemoveHeader(string name) => _headers.RemoveHeader(name); - - protected internal override IEnumerable EnumerateHeaders() => _headers.EnumerateHeaders(); - - public override string ClientRequestId - { - get => _clientRequestId ??= Guid.NewGuid().ToString(); - set - { - Argument.AssertNotNull(value, nameof(value)); - _clientRequestId = value; - } - } - - public override RequestContent? Content { get; set; } - - public override void Dispose() - { - var content = Content; - if (content != null) - { - Content = null; - content.Dispose(); - } - } - } - private static void ApplyOptionsToRequest(HttpWebRequest request, HttpPipelineTransportOptions options) { if (options == null) diff --git a/sdk/core/Azure.Core/src/Pipeline/Internal/DefaultRequestFailedDetailsParser.cs b/sdk/core/Azure.Core/src/Pipeline/Internal/DefaultRequestFailedDetailsParser.cs index 785f8f8102b0..3a7c7651d9e4 100644 --- a/sdk/core/Azure.Core/src/Pipeline/Internal/DefaultRequestFailedDetailsParser.cs +++ b/sdk/core/Azure.Core/src/Pipeline/Internal/DefaultRequestFailedDetailsParser.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Collections.Generic; namespace Azure.Core.Pipeline @@ -10,7 +11,41 @@ namespace Azure.Core.Pipeline /// internal class DefaultRequestFailedDetailsParser : RequestFailedDetailsParser { - public override bool TryParse(Response response, out ResponseError? error, out IDictionary? data) => - RequestFailedException.TryExtractErrorContent(response, out error, out data); + public override bool TryParse(Response response, out ResponseError? error, out IDictionary? data) + => TryParseDetails(response, out error, out data); + + public static bool TryParseDetails(Response response, out ResponseError? error, out IDictionary? data) + { + error = null; + data = null; + + try + { + // The response content is buffered at this point. + string? content = response.Content.ToString(); + + // Optimistic check for JSON object we expect + if (content == null || !content.StartsWith("{", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + // Try the ErrorResponse format and fallback to the ResponseError format. + +#if NET6_0_OR_GREATER + error = System.Text.Json.JsonSerializer.Deserialize(content, ResponseErrorSourceGenerationContext.Default.ErrorResponse)?.Error; + error ??= System.Text.Json.JsonSerializer.Deserialize(content, ResponseErrorSourceGenerationContext.Default.ResponseError); +#else + error = System.Text.Json.JsonSerializer.Deserialize(content)?.Error; + error ??= System.Text.Json.JsonSerializer.Deserialize(content); +#endif + } + catch (Exception) + { + // Ignore any failures - unexpected content will be + // included verbatim in the detailed error message + } + + return error != null; + } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs index fd4ae71e2d2e..49f5dfce21f9 100644 --- a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs @@ -28,7 +28,7 @@ public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory message.Response.RequestFailedDetailsParser = _errorParser; message.Response.Sanitizer = _sanitizer; - message.Response.IsError = message.ResponseClassifier.IsErrorResponse(message); + message.Response.SetIsError(message.ResponseClassifier.IsErrorResponse(message)); } public override void Process(HttpMessage message, ReadOnlyMemory pipeline) @@ -39,7 +39,7 @@ public override void Process(HttpMessage message, ReadOnlyMemory internal class ResponseBodyPolicy : HttpPipelinePolicy { - // Same value as Stream.CopyTo uses by default - private const int DefaultCopyBufferSize = 81920; - + private readonly ResponseBufferingPolicy _policy; private readonly TimeSpan _networkTimeout; public ResponseBodyPolicy(TimeSpan networkTimeout) { + _policy = new ResponseBufferingPolicy(); _networkTimeout = networkTimeout; } - public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline) => - ProcessAsync(message, pipeline, true); + public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline) + => await ProcessSyncOrAsync(message, pipeline, async: true).ConfigureAwait(false); - public override void Process(HttpMessage message, ReadOnlyMemory pipeline) => - ProcessAsync(message, pipeline, false).EnsureCompleted(); + public override void Process(HttpMessage message, ReadOnlyMemory pipeline) + => ProcessSyncOrAsync(message, pipeline, async: false).EnsureCompleted(); - private async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline, bool async) + private async ValueTask ProcessSyncOrAsync(HttpMessage message, ReadOnlyMemory pipeline, bool async) { - CancellationToken oldToken = message.CancellationToken; - using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(oldToken); + AzureCorePipelineProcessor processor = new(pipeline); - var networkTimeout = _networkTimeout; + // Get the network timeout for this particular invocation of the pipeline. + // We either use the default that the policy was constructed with at + // pipeline-creation time, or we get an override value from the message that + // we use for the duration of this invocation only. + message.NetworkTimeout ??= _networkTimeout; + TimeSpan invocationNetworkTimeout = (TimeSpan)message.NetworkTimeout!; - if (message.NetworkTimeout is TimeSpan networkTimeoutOverride) - { - networkTimeout = networkTimeoutOverride; - } - - cts.CancelAfter(networkTimeout); try { - message.CancellationToken = cts.Token; if (async) { - await ProcessNextAsync(message, pipeline).ConfigureAwait(false); + await _policy.ProcessAsync(message, processor, -1).ConfigureAwait(false); } else { - ProcessNext(message, pipeline); + _policy.Process(message, processor, -1); } } - catch (OperationCanceledException ex) - { - ThrowIfCancellationRequestedOrTimeout(oldToken, cts.Token, ex, networkTimeout); - throw; - } - finally - { - message.CancellationToken = oldToken; - cts.CancelAfter(Timeout.Infinite); - } - - Stream? responseContentStream = message.Response.ContentStream; - if (responseContentStream == null || responseContentStream.CanSeek) - { - return; - } - - if (message.BufferResponse) + catch (TaskCanceledException e) { - // If cancellation is possible (whether due to network timeout or a user cancellation token being passed), then - // register callback to dispose the stream on cancellation. - if (networkTimeout != Timeout.InfiniteTimeSpan || oldToken.CanBeCanceled) - { - cts.Token.Register(state => ((Stream?)state)?.Dispose(), responseContentStream); - } - - try + if (e.Message.Contains("The operation was cancelled because it exceeded the configured timeout")) { - var bufferedStream = new MemoryStream(); - if (async) - { - await CopyToAsync(responseContentStream, bufferedStream, cts).ConfigureAwait(false); - } - else - { - CopyTo(responseContentStream, bufferedStream, cts); - } - - responseContentStream.Dispose(); - bufferedStream.Position = 0; - message.Response.ContentStream = bufferedStream; - } - // We dispose stream on timeout or user cancellation so catch and check if cancellation token was cancelled - catch (Exception ex) - when (ex is ObjectDisposedException - or IOException - or OperationCanceledException - or NotSupportedException) - { - ThrowIfCancellationRequestedOrTimeout(oldToken, cts.Token, ex, networkTimeout); - throw; + string exceptionMessage = e.Message + + $"Network timeout can be adjusted in {nameof(ClientOptions)}.{nameof(ClientOptions.Retry)}.{nameof(RetryOptions.NetworkTimeout)}."; +#if NETCOREAPP2_1_OR_GREATER + throw new TaskCanceledException(exceptionMessage, e.InnerException, e.CancellationToken); +#else + throw new TaskCanceledException(exceptionMessage, e.InnerException); +#endif } - } - else if (networkTimeout != Timeout.InfiniteTimeSpan) - { - message.Response.ContentStream = new ReadTimeoutStream(responseContentStream, networkTimeout); - } - } - - private async Task CopyToAsync(Stream source, Stream destination, CancellationTokenSource cancellationTokenSource) - { - byte[] buffer = ArrayPool.Shared.Rent(DefaultCopyBufferSize); - try - { - while (true) - { - cancellationTokenSource.CancelAfter(_networkTimeout); -#pragma warning disable CA1835 // ReadAsync(Memory<>) overload is not available in all targets - int bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token).ConfigureAwait(false); -#pragma warning restore // ReadAsync(Memory<>) overload is not available in all targets - if (bytesRead == 0) break; - await destination.WriteAsync(new ReadOnlyMemory(buffer, 0, bytesRead), cancellationTokenSource.Token).ConfigureAwait(false); - } - } - finally - { - cancellationTokenSource.CancelAfter(Timeout.InfiniteTimeSpan); - ArrayPool.Shared.Return(buffer); - } - } - - private void CopyTo(Stream source, Stream destination, CancellationTokenSource cancellationTokenSource) - { - byte[] buffer = ArrayPool.Shared.Rent(DefaultCopyBufferSize); - try - { - int read; - while ((read = source.Read(buffer, 0, buffer.Length)) != 0) + else { - cancellationTokenSource.Token.ThrowIfCancellationRequested(); - cancellationTokenSource.CancelAfter(_networkTimeout); - destination.Write(buffer, 0, read); + throw e; } } - finally - { - cancellationTokenSource.CancelAfter(Timeout.InfiniteTimeSpan); - ArrayPool.Shared.Return(buffer); - } } /// Throws a cancellation exception if cancellation has been requested via or . diff --git a/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs b/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs index 5779d8da6a02..b30790a7ce5c 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; namespace Azure.Core @@ -14,7 +15,7 @@ public abstract class RequestFailedDetailsParser /// /// Parses the error details from the provided . /// - /// The to parse. The will already be buffered. + /// The to parse. The will already be buffered. /// The describing the parsed error details. /// Data to be applied to the property. /// true if successful, otherwise false. diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs new file mode 100644 index 000000000000..06b6a1ea95c5 --- /dev/null +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs @@ -0,0 +1,106 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel.Primitives; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core.Diagnostics; + +namespace Azure.Core.Pipeline; + +public partial class RetryPolicy +{ + internal class AzureCoreRetryPolicy : ClientRetryPolicy + { + private readonly RetryPolicy _pipelinePolicy; + private readonly DelayStrategy _delayStrategy; + + private long _beforeProcess; + private long _afterProcess; + private double _elapsedTime; + + public AzureCoreRetryPolicy(int maxRetries, DelayStrategy delay, RetryPolicy policy) + : base(maxRetries) + { + _delayStrategy = delay; + _pipelinePolicy = policy; + } + + protected override void OnSendingRequest(PipelineMessage message) + { + _beforeProcess = Stopwatch.GetTimestamp(); + + _pipelinePolicy.OnSendingRequest(AssertHttpMessage(message)); + } + + protected override async ValueTask OnSendingRequestAsync(PipelineMessage message) + { + _beforeProcess = Stopwatch.GetTimestamp(); + + await _pipelinePolicy.OnSendingRequestAsync(AssertHttpMessage(message)).ConfigureAwait(false); + } + + protected override void OnRequestSent(PipelineMessage message) + { + _pipelinePolicy.OnRequestSent(AssertHttpMessage(message)); + + _afterProcess = Stopwatch.GetTimestamp(); + _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; + } + + protected override async ValueTask OnRequestSentAsync(PipelineMessage message) + { + await _pipelinePolicy.OnRequestSentAsync(AssertHttpMessage(message)).ConfigureAwait(false); + + _afterProcess = Stopwatch.GetTimestamp(); + _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; + } + + protected override bool ShouldRetry(PipelineMessage message, Exception? exception) + => _pipelinePolicy.ShouldRetry(AssertHttpMessage(message), exception); + + protected override async ValueTask ShouldRetryAsync(PipelineMessage message, Exception? exception) + => await _pipelinePolicy.ShouldRetryAsync(AssertHttpMessage(message), exception).ConfigureAwait(false); + + protected override void OnTryComplete(PipelineMessage message) + { + HttpMessage httpMessage = AssertHttpMessage(message); + httpMessage.RetryNumber++; + + AzureCoreEventSource.Singleton.RequestRetrying(httpMessage.Request.ClientRequestId, httpMessage.RetryNumber, _elapsedTime); + + // Reset stopwatch values + _afterProcess = default; + _beforeProcess = default; + _elapsedTime = default; + } + + protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) + { + HttpMessage httpMessage = AssertHttpMessage(message); + + Debug.Assert(tryCount == httpMessage.RetryNumber); + + Response? response = httpMessage.HasResponse ? httpMessage.Response : default; + return _delayStrategy.GetNextDelay(response, tryCount + 1); + } + + protected override async Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) + => await _pipelinePolicy.WaitAsync(time, cancellationToken).ConfigureAwait(false); + + protected override void Wait(TimeSpan time, CancellationToken cancellationToken) + => _pipelinePolicy.Wait(time, cancellationToken); + + private static HttpMessage AssertHttpMessage(PipelineMessage message) + { + if (message is not HttpMessage httpMessage) + { + throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'."); + } + + return httpMessage; + } + } +} diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs index 915767a0c90c..b1873a04c6a5 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs @@ -2,36 +2,32 @@ // Licensed under the MIT License. using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.ExceptionServices; +using System.ClientModel.Primitives; using System.Threading; using System.Threading.Tasks; -using Azure.Core.Diagnostics; namespace Azure.Core.Pipeline { /// /// Represents a policy that can be overriden to customize whether or not a request will be retried and how long to wait before retrying. /// - public class RetryPolicy : HttpPipelinePolicy + public partial class RetryPolicy : HttpPipelinePolicy { private readonly int _maxRetries; - - /// - /// Gets the delay to use for computing the interval between retry attempts. - /// private readonly DelayStrategy _delayStrategy; + private readonly AzureCoreRetryPolicy _policy; /// /// Initializes a new instance of the class. /// /// The maximum number of retries to attempt. /// The delay to use for computing the interval between retry attempts. - public RetryPolicy(int maxRetries = 3, DelayStrategy? delayStrategy = default) + public RetryPolicy(int maxRetries = RetryOptions.DefaultMaxRetries, DelayStrategy? delayStrategy = default) { _maxRetries = maxRetries; _delayStrategy = delayStrategy ?? DelayStrategy.CreateExponentialDelayStrategy(); + + _policy = new AzureCoreRetryPolicy(maxRetries, _delayStrategy, this); } /// @@ -42,10 +38,8 @@ public RetryPolicy(int maxRetries = 3, DelayStrategy? delayStrategy = default) /// The this policy would be applied to. /// The set of to execute after current one. /// The representing the asynchronous operation. - public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline) - { - return ProcessAsync(message, pipeline, true); - } + public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline) + => await ProcessSyncOrAsync(message, pipeline, async: true).ConfigureAwait(false); /// /// This method can be overriden to take full control over the retry policy. If this is overriden and the base method isn't called, @@ -55,216 +49,109 @@ public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemoryThe this policy would be applied to. /// The set of to execute after current one. public override void Process(HttpMessage message, ReadOnlyMemory pipeline) - { - ProcessAsync(message, pipeline, false).EnsureCompleted(); - } + => ProcessSyncOrAsync(message, pipeline, async: false).EnsureCompleted(); - private async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline, bool async) + private async ValueTask ProcessSyncOrAsync(HttpMessage message, ReadOnlyMemory pipeline, bool async) { - List? exceptions = null; - while (true) - { - Exception? lastException = null; - var before = Stopwatch.GetTimestamp(); - if (async) - { - await OnSendingRequestAsync(message).ConfigureAwait(false); - } - else - { - OnSendingRequest(message); - } - try - { - if (async) - { - await ProcessNextAsync(message, pipeline).ConfigureAwait(false); - } - else - { - ProcessNext(message, pipeline); - } - } - catch (Exception ex) - { - if (exceptions == null) - { - exceptions = new List(); - } - - exceptions.Add(ex); - - lastException = ex; - } + AzureCorePipelineProcessor processor = new(pipeline); + try + { if (async) { - await OnRequestSentAsync(message).ConfigureAwait(false); + await _policy.ProcessAsync(message, processor, -1).ConfigureAwait(false); } else { - OnRequestSent(message); - } - - var after = Stopwatch.GetTimestamp(); - double elapsed = (after - before) / (double)Stopwatch.Frequency; - - bool shouldRetry = false; - - // We only invoke ShouldRetry for errors. If a user needs full control they can either override HttpPipelinePolicy directly - // or modify the ResponseClassifier. - - if (lastException != null || (message.HasResponse && message.Response.IsError)) - { - shouldRetry = async ? await ShouldRetryAsync(message, lastException).ConfigureAwait(false) : ShouldRetry(message, lastException); + _policy.Process(message, processor, -1); } - - if (shouldRetry) - { - var retryAfter = message.HasResponse ? message.Response.Headers.RetryAfter : default; - TimeSpan delay = async ? await GetNextDelayAsync(message, retryAfter).ConfigureAwait(false) : GetNextDelay(message, retryAfter); - if (delay > TimeSpan.Zero) - { - if (async) - { - await WaitAsync(delay, message.CancellationToken).ConfigureAwait(false); - } - else - { - Wait(delay, message.CancellationToken); - } - } - - if (message.HasResponse) - { - // Dispose the content stream to free up a connection if the request has any - message.Response.ContentStream?.Dispose(); - } - - message.RetryNumber++; - AzureCoreEventSource.Singleton.RequestRetrying(message.Request.ClientRequestId, message.RetryNumber, elapsed); - continue; - } - - if (lastException != null) + } + catch (AggregateException e) + { + if (e.Message.StartsWith("Retry failed after")) { - // Rethrow a singular exception - if (exceptions!.Count == 1) - { - ExceptionDispatchInfo.Capture(lastException).Throw(); - } - - throw new AggregateException( - $"Retry failed after {message.RetryNumber + 1} tries. Retry settings can be adjusted in {nameof(ClientOptions)}.{nameof(ClientOptions.Retry)}" + - $" or by configuring a custom retry policy in {nameof(ClientOptions)}.{nameof(ClientOptions.RetryPolicy)}.", - exceptions); + string exceptionMessage = e.Message + + $"Retry settings can be adjusted in {nameof(ClientOptions)}.{nameof(ClientOptions.Retry)}" + + $" or by configuring a custom retry policy in {nameof(ClientOptions)}.{nameof(ClientOptions.RetryPolicy)}."; + + // Create a new exception from the thrown exception to keep the + // collection of inner exceptions at the same level as the one + // thrown by the ClientModel policy. + throw new AggregateException(exceptionMessage, e.InnerExceptions); } - // We are not retrying and the last attempt didn't result in an exception. - break; + throw e; } } - internal virtual async Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) - { - await Task.Delay(time, cancellationToken).ConfigureAwait(false); - } - - internal virtual void Wait(TimeSpan time, CancellationToken cancellationToken) - { - cancellationToken.WaitHandle.WaitOne(time); - } - /// /// This method can be overriden to control whether a request should be retried. It will be called for any response where - /// is true, or if an exception is thrown from any subsequent pipeline policies or the transport. + /// is true, or if an exception is thrown from any subsequent pipeline policies or the transport. /// This method will only be called for sync methods. /// /// The message containing the request and response. /// The exception that occurred, if any, which can be used to determine if a retry should occur. /// Whether or not to retry. - protected internal virtual bool ShouldRetry(HttpMessage message, Exception? exception) => ShouldRetryInternal(message, exception); - - /// - /// This method can be overriden to control whether a request should be retried. It will be called for any response where - /// is true, or if an exception is thrown from any subsequent pipeline policies or the transport. - /// This method will only be called for async methods. - /// - /// The message containing the request and response. - /// The exception that occurred, if any, which can be used to determine if a retry should occur. - /// Whether or not to retry. - protected internal virtual ValueTask ShouldRetryAsync(HttpMessage message, Exception? exception) => new(ShouldRetryInternal(message, exception)); - - private bool ShouldRetryInternal(HttpMessage message, Exception? exception) + protected virtual bool ShouldRetry(HttpMessage message, Exception? exception) { - if (message.RetryNumber < _maxRetries) + if (message.RetryNumber >= _maxRetries) { - if (exception != null) - { - return message.ResponseClassifier.IsRetriable(message, exception); - } - - // Response.IsError is true if we get here - return message.ResponseClassifier.IsRetriableResponse(message); + // We've exceeded the maximum number of retries, so don't retry. + return false; } - // out of retries - return false; + return exception is null ? + message.ResponseClassifier.IsRetriableResponse(message) : + message.ResponseClassifier.IsRetriable(message, exception); } /// - /// This method can be overriden to control how long to delay before retrying. This method will only be called for sync methods. - /// - /// The message containing the request and response. - /// The Retry-After header value, if any, returned from the service. - /// The amount of time to delay before retrying. - internal TimeSpan GetNextDelay(HttpMessage message, TimeSpan? retryAfter) => GetNextDelayInternal(message); - - /// - /// This method can be overriden to control how long to delay before retrying. This method will only be called for async methods. + /// This method can be overriden to control whether a request should be retried. It will be called for any response where + /// is true, or if an exception is thrown from any subsequent pipeline policies or the transport. + /// This method will only be called for async methods. /// /// The message containing the request and response. - /// The Retry-After header value, if any, returned from the service. - /// The amount of time to delay before retrying. - internal ValueTask GetNextDelayAsync(HttpMessage message, TimeSpan? retryAfter) => new(GetNextDelayInternal(message)); + /// The exception that occurred, if any, which can be used to determine if a retry should occur. + /// Whether or not to retry. + protected virtual ValueTask ShouldRetryAsync(HttpMessage message, Exception? exception) + => new(ShouldRetry(message, exception)); /// /// This method can be overridden to introduce logic before each request attempt is sent. This will run even for the first attempt. /// This method will only be called for sync methods. /// /// The message containing the request and response. - protected internal virtual void OnSendingRequest(HttpMessage message) - { - } + protected virtual void OnSendingRequest(HttpMessage message) { } /// /// This method can be overriden to introduce logic that runs before the request is sent. This will run even for the first attempt. /// This method will only be called for async methods. /// /// The message containing the request and response. - protected internal virtual ValueTask OnSendingRequestAsync(HttpMessage message) => default; + protected virtual ValueTask OnSendingRequestAsync(HttpMessage message) => default; /// /// This method can be overridden to introduce logic that runs after the request is sent through the pipeline and control is returned to the retry /// policy. This method will only be called for sync methods. /// /// The message containing the request and response. - protected internal virtual void OnRequestSent(HttpMessage message) - { - } + protected virtual void OnRequestSent(HttpMessage message) { } /// /// This method can be overridden to introduce logic that runs after the request is sent through the pipeline and control is returned to the retry /// policy. This method will only be called for async methods. /// /// The message containing the request and response. - protected internal virtual ValueTask OnRequestSentAsync(HttpMessage message) => default; + protected virtual ValueTask OnRequestSentAsync(HttpMessage message) => default; - private TimeSpan GetNextDelayInternal(HttpMessage message) + internal virtual async Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) { - return _delayStrategy.GetNextDelay( - message.HasResponse ? message.Response : default, - message.RetryNumber + 1); + await Task.Delay(time, cancellationToken).ConfigureAwait(false); + } + + internal virtual void Wait(TimeSpan time, CancellationToken cancellationToken) + { + cancellationToken.WaitHandle.WaitOne(time); } } } diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index 011af269df7b..1da30c23ee7f 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -2,9 +2,10 @@ // Licensed under the MIT License. using System; +using System.ClientModel; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Net.Http; using Azure.Core.Pipeline; namespace Azure.Core @@ -13,36 +14,117 @@ namespace Azure.Core /// Represents an HTTP request. Use or to create an instance. /// #pragma warning disable AZC0012 // Avoid single word type names - public abstract class Request : IDisposable + public abstract class Request : PipelineRequest #pragma warning restore AZC0012 // Avoid single word type names { - private RequestUriBuilder? _uri; + private RequestMethod _method; + private RequestUriBuilder? _uriBuilder; + private RequestContent? _content; + + private string? _clientRequestId; + + /// + /// Gets or sets the request HTTP method. + /// + public new virtual RequestMethod Method + { + get => _method; + set => SetMethodCore(value.Method); + } /// /// Gets or sets and instance of used to create the Uri. /// - public virtual RequestUriBuilder Uri + public new virtual RequestUriBuilder Uri { - get + get => _uriBuilder ??= new RequestUriBuilder(); + set { - return _uri ??= new RequestUriBuilder(); + Argument.AssertNotNull(value, nameof(value)); + + _uriBuilder = value; } + } + + /// + /// Gets or sets the request content. + /// + public new virtual RequestContent? Content + { + get => (RequestContent?)GetContentCore(); + set => SetContentCore(value); + } + + /// + /// Gets or sets the client request id that was sent to the server as x-ms-client-request-id headers. + /// + public virtual string ClientRequestId + { + get => _clientRequestId ??= Guid.NewGuid().ToString(); set { Argument.AssertNotNull(value, nameof(value)); - _uri = value; + _clientRequestId = value; } } /// - /// Gets or sets the request HTTP method. + /// Gets the request HTTP headers. /// - public virtual RequestMethod Method { get; set; } + public new RequestHeaders Headers => new(this); + + #region Overrides for "Core" methods from the PipelineRequest Template pattern /// - /// Gets or sets the request content. + /// TBD. /// - public virtual RequestContent? Content { get; set; } + /// + protected override string GetMethodCore() + => _method.Method; + + /// + /// TBD. + /// + /// + protected override void SetMethodCore(string method) + => _method = RequestMethod.Parse(method); + + /// + /// TBD. + /// + /// + protected override Uri GetUriCore() + => Uri.ToUri(); + + /// + /// TBD. + /// + /// + protected override void SetUriCore(Uri uri) + => Uri.Reset(uri); + + /// + /// TBD. + /// + /// + protected override BinaryContent? GetContentCore() + => _content; + + /// + /// TBD. + /// + /// + protected override void SetContentCore(BinaryContent? content) + => _content = (RequestContent?)content; + + /// + /// TBD. + /// + /// + protected override PipelineRequestHeaders GetHeadersCore() + => new AzureCoreMessageHeaders(Headers); + + #endregion /// /// Adds a header value to the header collection. @@ -98,18 +180,43 @@ protected internal virtual void SetHeader(string name, string value) protected internal abstract IEnumerable EnumerateHeaders(); /// - /// Gets or sets the client request id that was sent to the server as x-ms-client-request-id headers. + /// Backwards adapter to MessageHeaders to implement GetHeadersCore /// - public abstract string ClientRequestId { get; set; } + private sealed class AzureCoreMessageHeaders : PipelineRequestHeaders + { + /// + /// Headers on the Azure.Core.Request type to adapt to. + /// + private readonly RequestHeaders _headers; - /// - /// Gets the response HTTP headers. - /// - public RequestHeaders Headers => new(this); + public AzureCoreMessageHeaders(RequestHeaders headers) + => _headers = headers; - /// - /// Frees resources held by this instance. - /// - public abstract void Dispose(); + public override void Add(string name, string value) + => _headers.Add(name, value); + + public override bool Remove(string name) + => _headers.Remove(name); + + public override void Set(string name, string value) + => _headers.SetValue(name, value); + + public override IEnumerator> GetEnumerator() + => GetHeadersCompositeValues().GetEnumerator(); + + private IEnumerable> GetHeadersCompositeValues() + { + foreach (HttpHeader header in _headers) + { + yield return new KeyValuePair(header.Name, header.Value); + } + } + + public override bool TryGetValue(string name, out string? value) + => _headers.TryGetValue(name, out value); + + public override bool TryGetValues(string name, out IEnumerable? values) + => _headers.TryGetValues(name, out values); + } } } diff --git a/sdk/core/Azure.Core/src/RequestContent.cs b/sdk/core/Azure.Core/src/RequestContent.cs index 439b2aa0178f..0cd1a3db94cf 100644 --- a/sdk/core/Azure.Core/src/RequestContent.cs +++ b/sdk/core/Azure.Core/src/RequestContent.cs @@ -3,6 +3,8 @@ using System; using System.Buffers; +using System.ClientModel; +using System.ClientModel.Primitives; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -17,8 +19,10 @@ namespace Azure.Core /// /// Represents the content sent as part of the . /// - public abstract class RequestContent : IDisposable + public abstract class RequestContent : BinaryContent { + private static readonly ModelReaderWriterOptions ModelWriteWireOptions = new ModelReaderWriterOptions("W"); + internal const string SerializationRequiresUnreferencedCode = "This method uses reflection-based serialization which is incompatible with trimming. Try using one of the 'Create' overloads that doesn't wrap a serialized version of an object."; private static readonly Encoding s_UTF8NoBomEncoding = new UTF8Encoding(false); @@ -72,7 +76,7 @@ public abstract class RequestContent : IDisposable /// /// The to use. /// An instance of that wraps a . - public static RequestContent Create(BinaryData content) => new MemoryContent(content.ToMemory()); + public static new RequestContent Create(BinaryData content) => new MemoryContent(content.ToMemory()); /// /// Creates an instance of that wraps a . @@ -81,6 +85,15 @@ public abstract class RequestContent : IDisposable /// An instance of that wraps a . public static RequestContent Create(DynamicData content) => new DynamicDataContent(content); + /// + /// Creates an instance of that wraps a . + /// + /// The to write. + /// The to use. + /// An instance of that wraps a a . + public static new RequestContent Create(T model, ModelReaderWriterOptions? options = default) where T : IPersistableModel + => new AzureInputContent(BinaryContent.Create(model, options ?? ModelWriteWireOptions)); + /// /// Creates an instance of that wraps a serialized version of an object. /// @@ -139,30 +152,27 @@ public static RequestContent Create(object serializable, JsonPropertyNames prope /// The to use. public static implicit operator RequestContent(DynamicData content) => Create(content); - /// - /// 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); + private sealed class AzureInputContent : RequestContent + { + private readonly BinaryContent _content; - /// - /// 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); + public AzureInputContent(BinaryContent content) + { + _content = content; + } - /// - /// Attempts to compute the length of the underlying content, if available. - /// - /// The length of the underlying data. - public abstract bool TryComputeLength(out long length); + public override void Dispose() + => _content?.Dispose(); - /// - /// Frees resources held by the object. - /// - public abstract void Dispose(); + public override bool TryComputeLength(out long length) + => _content.TryComputeLength(out length); + + public override void WriteTo(Stream stream, CancellationToken cancellationToken) + => _content.WriteTo(stream, cancellationToken); + + public override async Task WriteToAsync(Stream stream, CancellationToken cancellationToken) + => await _content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); + } private sealed class StreamContent : RequestContent { diff --git a/sdk/core/Azure.Core/src/RequestContext.cs b/sdk/core/Azure.Core/src/RequestContext.cs index 45b1b4c53d7a..de5e5cbaf1e2 100644 --- a/sdk/core/Azure.Core/src/RequestContext.cs +++ b/sdk/core/Azure.Core/src/RequestContext.cs @@ -2,8 +2,8 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Threading; using Azure.Core; using Azure.Core.Pipeline; @@ -12,10 +12,8 @@ namespace Azure /// /// Options that can be used to control the behavior of a request sent by a client. /// - public class RequestContext + public class RequestContext : RequestOptions { - private bool _frozen; - private (int Status, bool IsError)[]? _statusCodes; internal (int Status, bool IsError)[]? StatusCodes => _statusCodes; @@ -27,12 +25,31 @@ public class RequestContext /// /// Controls under what conditions the operation raises an exception if the underlying response indicates a failure. /// - public ErrorOptions ErrorOptions { get; set; } = ErrorOptions.Default; + public new ErrorOptions ErrorOptions + { + get => FromResponseErrorOptions(base.ErrorOptions); + set => base.ErrorOptions = ToResponseErrorOptions(value); + } - /// - /// The token to check for cancellation. - /// - public CancellationToken CancellationToken { get; set; } = CancellationToken.None; + private static ErrorOptions FromResponseErrorOptions(ClientErrorBehaviors options) + { + return options switch + { + ClientErrorBehaviors.Default => ErrorOptions.Default, + ClientErrorBehaviors.NoThrow => ErrorOptions.NoThrow, + _ => throw new NotSupportedException(), + }; + } + + private static ClientErrorBehaviors ToResponseErrorOptions(ErrorOptions options) + { + return options switch + { + ErrorOptions.Default => ClientErrorBehaviors.Default, + ErrorOptions.NoThrow => ClientErrorBehaviors.NoThrow, + _ => throw new NotSupportedException(), + }; + } /// /// Initializes a new instance of the class. @@ -79,10 +96,7 @@ public void AddClassifier(int statusCode, bool isError) { Argument.AssertInRange(statusCode, 100, 599, nameof(statusCode)); - if (_frozen) - { - throw new InvalidOperationException("Cannot modify classifiers after this type has been used in a method call."); - } + AssertNotFrozen(); int length = _statusCodes == null ? 0 : _statusCodes.Length; Array.Resize(ref _statusCodes, length + 1); @@ -105,10 +119,7 @@ public void AddClassifier(int statusCode, bool isError) /// used in a method call. public void AddClassifier(ResponseClassificationHandler classifier) { - if (_frozen) - { - throw new InvalidOperationException("Cannot modify classifiers after this type has been used in a method call."); - } + AssertNotFrozen(); int length = _handlers == null ? 0 : _handlers.Length; Array.Resize(ref _handlers, length + 1); @@ -116,11 +127,6 @@ public void AddClassifier(ResponseClassificationHandler classifier) _handlers[0] = classifier; } - internal void Freeze() - { - _frozen = true; - } - internal ResponseClassifier Apply(ResponseClassifier classifier) { if (_statusCodes == null && _handlers == null) diff --git a/sdk/core/Azure.Core/src/RequestFailedException.cs b/sdk/core/Azure.Core/src/RequestFailedException.cs index 734b91784169..2b93d44047f6 100644 --- a/sdk/core/Azure.Core/src/RequestFailedException.cs +++ b/sdk/core/Azure.Core/src/RequestFailedException.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; @@ -13,40 +14,69 @@ namespace Azure { -#pragma warning disable CA2229, CA2235 // False positive /// /// An exception thrown when service request fails. /// [Serializable] - public class RequestFailedException : Exception, ISerializable + public class RequestFailedException : ClientResultException, ISerializable { private const string DefaultMessage = "Service request failed."; - /// - /// Gets the HTTP status code of the response. Returns. 0 if response was not received. - /// - public int Status { get; } - /// /// Gets the service specific error code if available. Please refer to the client documentation for the list of supported error codes. /// public string? ErrorCode { get; } - /// - /// Gets the response, if any, that led to the exception. - /// - private readonly Response? _response; + #region Response constructors - /// Initializes a new instance of the class with a specified error message. - /// The message that describes the error. - public RequestFailedException(string message) : this(0, message) + /// Initializes a new instance of the class + /// with an error message, HTTP status code, and error code obtained from the specified response. + /// The response to obtain error details from. + public RequestFailedException(Response response) + : this(response, null) { } - /// Initializes a new instance of the class with a specified error message, HTTP status code and a reference to the inner exception that is the cause of this exception. - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public RequestFailedException(string message, Exception? innerException) : this(0, message, innerException) + /// Initializes a new instance of the class + /// with an error message, HTTP status code, and error code obtained from the specified response. + /// The response to obtain error details from. + /// An inner exception to associate with the new . + public RequestFailedException(Response response, Exception? innerException) + : this(response, innerException, null) + { + } + + /// Initializes a new instance of the class + /// with an error message, HTTP status code, and error code obtained from the specified response. + /// The response to obtain error details from. + /// An inner exception to associate with the new . + /// The parser to use to parse the response content. + public RequestFailedException(Response response, Exception? innerException, RequestFailedDetailsParser? detailsParser) + : this(response, CreateRequestFailedExceptionContent(response, detailsParser), innerException) + { + } + + private RequestFailedException(Response response, ErrorDetails details, Exception? innerException) + : base(details.Message, response, innerException) + { + ErrorCode = details.ErrorCode; + + if (details.Data != null) + { + foreach (KeyValuePair keyValuePair in details.Data) + { + Data.Add(keyValuePair.Key, keyValuePair.Value); + } + } + } + + #endregion + + #region No-Response constructors + + /// Initializes a new instance of the class with a specified error message. + /// The message that describes the error. + public RequestFailedException(string message) : this(0, message) { } @@ -59,6 +89,14 @@ public RequestFailedException(int status, string message) { } + /// Initializes a new instance of the class with a specified error message, HTTP status code and a reference to the inner exception that is the cause of this exception. + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public RequestFailedException(string message, Exception? innerException) + : this(0, message, innerException) + { + } + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. /// The HTTP status code, or 0 if not available. /// The error message that explains the reason for the exception. @@ -76,62 +114,20 @@ public RequestFailedException(int status, string message, Exception? innerExcept /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. [EditorBrowsable(EditorBrowsableState.Never)] public RequestFailedException(int status, string message, string? errorCode, Exception? innerException) - : base(message, innerException) + : base(message, default, innerException) { Status = status; ErrorCode = errorCode; } - internal RequestFailedException(int status, (string Message, ResponseError? Error) details) : - this(status, details.Message, details.Error?.Code, null) - { - } - - internal RequestFailedException(int status, (string FormatMessage, string? ErrorCode, IDictionary? Data) details, Exception? innerException) : - this(status, details.FormatMessage, details.ErrorCode, innerException) - { - if (details.Data != null) - { - foreach (KeyValuePair keyValuePair in details.Data) - { - Data.Add(keyValuePair.Key, keyValuePair.Value); - } - } - } - - /// Initializes a new instance of the class - /// with an error message, HTTP status code, and error code obtained from the specified response. - /// The response to obtain error details from. - public RequestFailedException(Response response) - : this(response, null) - { - } - - /// Initializes a new instance of the class - /// with an error message, HTTP status code, and error code obtained from the specified response. - /// The response to obtain error details from. - /// An inner exception to associate with the new . - public RequestFailedException(Response response, Exception? innerException) - : this(response, innerException, null) - { - } + #endregion - /// Initializes a new instance of the class - /// with an error message, HTTP status code, and error code obtained from the specified response. - /// The response to obtain error details from. - /// An inner exception to associate with the new . - /// The parser to use to parse the response content. - public RequestFailedException(Response response, Exception? innerException, RequestFailedDetailsParser? detailsParser) - : this(response.Status, GetRequestFailedExceptionContent(response, detailsParser), innerException) - { - _response = response; - } + #region ISerializable implementation /// protected RequestFailedException(SerializationInfo info, StreamingContext context) : base(info, context) { - Status = info.GetInt32(nameof(Status)); ErrorCode = info.GetString(nameof(ErrorCode)); } @@ -140,23 +136,28 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont { Argument.AssertNotNull(info, nameof(info)); - info.AddValue(nameof(Status), Status); info.AddValue(nameof(ErrorCode), ErrorCode); base.GetObjectData(info, context); } + #endregion + /// /// Gets the response, if any, that led to the exception. /// - public Response? GetRawResponse() => _response; + public new Response? GetRawResponse() => (Response?)base.GetRawResponse(); - internal static (string FormattedError, string? ErrorCode, IDictionary? Data) GetRequestFailedExceptionContent(Response response, RequestFailedDetailsParser? parser) + private static ErrorDetails CreateRequestFailedExceptionContent(Response response, RequestFailedDetailsParser? parser) { BufferResponseIfNeeded(response); + parser ??= response.RequestFailedDetailsParser; - bool parseSuccess = parser == null ? TryExtractErrorContent(response, out ResponseError? error, out IDictionary? additionalInfo) : parser.TryParse(response, out error, out additionalInfo); + bool parseSuccess = parser == null ? + DefaultRequestFailedDetailsParser.TryParseDetails(response, out ResponseError? error, out IDictionary? additionalInfo) : + parser.TryParse(response, out error, out additionalInfo); + if (!parseSuccess) { error = null; @@ -220,8 +221,7 @@ internal static (string FormattedError, string? ErrorCode, IDictionary? data) + // This class needs to be internal rather than private so that it can be used + // by the System.Text.Json source generator. + internal class ErrorResponse { - error = null; - data = null; - - try - { - // The response content is buffered at this point. - string? content = response.Content.ToString(); + [System.Text.Json.Serialization.JsonPropertyName("error")] + public ResponseError? Error { get; set; } + } - // Optimistic check for JSON object we expect - if (content == null || !content.StartsWith("{", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - // Try the ErrorResponse format and fallback to the ResponseError format. - -#if NET6_0_OR_GREATER - error = System.Text.Json.JsonSerializer.Deserialize(content, ResponseErrorSourceGenerationContext.Default.ErrorResponse)?.Error; - error ??= System.Text.Json.JsonSerializer.Deserialize(content, ResponseErrorSourceGenerationContext.Default.ResponseError); -#else - error = System.Text.Json.JsonSerializer.Deserialize(content)?.Error; - error ??= System.Text.Json.JsonSerializer.Deserialize(content); -#endif - } - catch (Exception) + private readonly struct ErrorDetails + { + public ErrorDetails(string message, string? errorCode, IDictionary? data) { - // Ignore any failures - unexpected content will be - // included verbatim in the detailed error message + Message = message; + ErrorCode = errorCode; + Data = data; } - return error != null; - } + public string Message { get; } - // This class needs to be internal rather than private so that it can be used by the System.Text.Json source generator - internal class ErrorResponse - { - [System.Text.Json.Serialization.JsonPropertyName("error")] - public ResponseError? Error { get; set; } + public string? ErrorCode { get; } + + public IDictionary? Data { get; } } } } diff --git a/sdk/core/Azure.Core/src/RequestUriBuilder.cs b/sdk/core/Azure.Core/src/RequestUriBuilder.cs index c153c9f6caa2..6b04523e44ab 100644 --- a/sdk/core/Azure.Core/src/RequestUriBuilder.cs +++ b/sdk/core/Azure.Core/src/RequestUriBuilder.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics; -using System.IO; using System.Text; namespace Azure.Core @@ -29,6 +28,8 @@ public class RequestUriBuilder private string? _scheme; + internal bool IsValidUri => Scheme != null && Host != null; + /// /// Gets or sets the scheme name of the URI. /// diff --git a/sdk/core/Azure.Core/src/Response.cs b/sdk/core/Azure.Core/src/Response.cs index b602db8621c6..6efa478996bb 100644 --- a/sdk/core/Azure.Core/src/Response.cs +++ b/sdk/core/Azure.Core/src/Response.cs @@ -2,7 +2,9 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.IO; using Azure.Core; @@ -13,24 +15,9 @@ namespace Azure /// Represents the HTTP response from the service. /// #pragma warning disable AZC0012 // Avoid single word type names - public abstract class Response : IDisposable + public abstract class Response : PipelineResponse #pragma warning restore AZC0012 // Avoid single word type names { - /// - /// Gets the HTTP status code. - /// - public abstract int Status { get; } - - /// - /// Gets the HTTP reason phrase. - /// - public abstract string ReasonPhrase { get; } - - /// - /// Gets the contents of HTTP response. Returns null for responses without content. - /// - public abstract Stream? ContentStream { get; set; } - /// /// Gets the client request id that was sent to the server as x-ms-client-request-id headers. /// @@ -39,59 +26,44 @@ public abstract class Response : IDisposable /// /// Get the HTTP response headers. /// - public virtual ResponseHeaders Headers => new ResponseHeaders(this); - - // TODO(matell): The .NET Framework team plans to add BinaryData.Empty in dotnet/runtime#49670, and we can use it then. - private static readonly BinaryData s_EmptyBinaryData = new BinaryData(Array.Empty()); + // TODO: is is possible to not new-slot this? + public new virtual ResponseHeaders Headers => new ResponseHeaders(this); /// /// Gets the contents of HTTP response, if it is available. /// /// - /// Throws when is not a . + /// Throws when is not a . /// - public virtual BinaryData Content - { - get - { - if (ContentStream == null) - { - return s_EmptyBinaryData; - } - - MemoryStream? memoryContent = ContentStream as MemoryStream; - - if (memoryContent == null) - { - throw new InvalidOperationException($"The response is not fully buffered."); - } - - if (memoryContent.TryGetBuffer(out ArraySegment segment)) - { - return new BinaryData(segment.AsMemory()); - } - else - { - return new BinaryData(memoryContent.ToArray()); - } - } - } + public new virtual BinaryData Content => base.Content; /// - /// Frees resources held by this instance. + /// TBD. /// - public abstract void Dispose(); - - /// - /// Indicates whether the status code of the returned response is considered - /// an error code. - /// - public virtual bool IsError { get; internal set; } + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override PipelineResponseHeaders GetHeadersCore() + { + // TODO: we'll need to add an adapter in case someone were to override this. + throw new NotImplementedException(); + } internal HttpMessageSanitizer Sanitizer { get; set; } = HttpMessageSanitizer.Default; internal RequestFailedDetailsParser? RequestFailedDetailsParser { get; set; } + internal void SetIsError(bool value) => SetIsErrorCore(value); + + /// + /// TBD. + /// + /// + // Azure.Core overrides this only so it can seal it. + [EditorBrowsable(EditorBrowsableState.Never)] + protected sealed override void SetIsErrorCore(bool isError) + => base.SetIsErrorCore(isError); + /// /// Returns header value if the header is stored in the collection. If header has multiple values they are going to be joined with a comma. /// @@ -129,9 +101,7 @@ public virtual BinaryData Content /// The HTTP response. /// A new instance of with the provided value and HTTP response. public static Response FromValue(T value, Response response) - { - return new ValueResponse(response, value); - } + => new AzureCoreResponse(value, response); /// /// Returns the string representation of this . @@ -154,5 +124,64 @@ internal static void DisposeStreamIfNotBuffered(ref Stream? stream) stream = null; } } + + #region Private implementation subtypes of abstract Response types + private class AzureCoreResponse : Response + { + public AzureCoreResponse(T value, Response response) + : base(value, response) { } + } + + internal class AzureCoreDefaultResponse : Response + { + private readonly string DefaultMessage = "Types derived from abstract Response must provide an implementation of the virtual GetRawResponse method that returns a non-null Response value."; + + public override string ClientRequestId + { + get => throw new NotSupportedException(DefaultMessage); + set => throw new NotSupportedException(DefaultMessage); + } + + public override int Status => throw new NotSupportedException(DefaultMessage); + + public override string ReasonPhrase => throw new NotSupportedException(DefaultMessage); + + public override Stream? ContentStream + { + get => throw new NotSupportedException(DefaultMessage); + set => throw new NotSupportedException(DefaultMessage); + } + + protected override PipelineResponseHeaders GetHeadersCore() + { + throw new NotSupportedException(DefaultMessage); + } + + public override void Dispose() + { + throw new NotSupportedException(DefaultMessage); + } + + protected internal override bool ContainsHeader(string name) + { + throw new NotSupportedException(DefaultMessage); + } + + protected internal override IEnumerable EnumerateHeaders() + { + throw new NotSupportedException(DefaultMessage); + } + + protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) + { + throw new NotSupportedException(DefaultMessage); + } + + protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) + { + throw new NotSupportedException(DefaultMessage); + } + } + #endregion } } diff --git a/sdk/core/Azure.Core/src/ResponseClassifier.cs b/sdk/core/Azure.Core/src/ResponseClassifier.cs index 483c5dcbc73e..8986234a22b2 100644 --- a/sdk/core/Azure.Core/src/ResponseClassifier.cs +++ b/sdk/core/Azure.Core/src/ResponseClassifier.cs @@ -2,6 +2,9 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; +using System.ComponentModel; +using System.Diagnostics; using System.IO; namespace Azure.Core @@ -10,7 +13,7 @@ namespace Azure.Core /// A type that analyzes HTTP responses and exceptions and determines if they should be retried, /// and/or analyzes responses and determines if they should be treated as error responses. /// - public class ResponseClassifier + public class ResponseClassifier : PipelineMessageClassifier { internal static ResponseClassifier Shared { get; } = new(); @@ -19,18 +22,11 @@ public class ResponseClassifier /// public virtual bool IsRetriableResponse(HttpMessage message) { - switch (message.Response.Status) - { - case 408: // Request Timeout - case 429: // Too Many Requests - case 500: // Internal Server Error - case 502: // Bad Gateway - case 503: // Service Unavailable - case 504: // Gateway Timeout - return true; - default: - return false; - } + bool classified = Default.TryClassify(message, exception: default, out bool isRetriable); + + Debug.Assert(classified); + + return isRetriable; } /// @@ -47,9 +43,13 @@ public virtual bool IsRetriableException(Exception exception) /// public virtual bool IsRetriable(HttpMessage message, Exception exception) { + // Azure.Core cannot use default logic in this case to support end-user overrides + // of virtual IsRetriableException method. + return IsRetriableException(exception) || - // Retry non-user initiated cancellations - (exception is OperationCanceledException && !message.CancellationToken.IsCancellationRequested); + // Retry non-user initiated cancellations + (exception is OperationCanceledException && + !message.CancellationToken.IsCancellationRequested); } /// @@ -57,8 +57,63 @@ public virtual bool IsRetriable(HttpMessage message, Exception exception) /// public virtual bool IsErrorResponse(HttpMessage message) { - var statusKind = message.Response.Status / 100; - return statusKind == 4 || statusKind == 5; + bool classified = Default.TryClassify(message, out bool isError); + + Debug.Assert(classified); + + return isError; + } + + /// + /// TBD. + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + // TODO: Add a test that breaks if we unseal this to prevent that from happening + // Note: this is sealed to force the base type to call through to any overridden virtual methods + // on a subtype of ResponseClassifier. + public sealed override bool TryClassify(PipelineMessage message, out bool isError) + { + HttpMessage httpMessage = AssertHttpMessage(message); + + isError = IsErrorResponse(httpMessage); + + return true; + } + + /// + /// TBD. + /// + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + // TODO: Add a test that breaks if we unseal this to prevent that from happening + // Note: this is sealed to force the base type to call through to any overridden virtual methods + // on a subtype of ResponseClassifier. + public sealed override bool TryClassify(PipelineMessage message, Exception? exception, out bool isRetriable) + { + HttpMessage httpMessage = AssertHttpMessage(message); + + isRetriable = exception is null ? + IsRetriableResponse(httpMessage) : + IsRetriable(httpMessage, exception); + + return true; + } + + // TODO: remove duplication with this and other instances + private static HttpMessage AssertHttpMessage(PipelineMessage message) + { + if (message is not HttpMessage httpMessage) + { + throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'."); + } + + return httpMessage; } } } diff --git a/sdk/core/Azure.Core/src/ResponseOfT.cs b/sdk/core/Azure.Core/src/ResponseOfT.cs index 0dbded789a53..1b56dbd76bb3 100644 --- a/sdk/core/Azure.Core/src/ResponseOfT.cs +++ b/sdk/core/Azure.Core/src/ResponseOfT.cs @@ -18,12 +18,31 @@ public abstract class Response : NullableResponse #pragma warning restore AZC0012 // Avoid single word type names #pragma warning restore SA1649 // File name should match first type name { + /// + /// TBD. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected Response() : base(default, DefaultResponse) + { + // Added for back-compat with GA APIs. Any type that derives from + // Response must provide an implementation for GetRawResponse that + // replaces DefaultResponse with the Response populated on HttpMessage + // during the call to pipeline.Send. + } + + /// + /// TBD. + /// + /// + /// + protected Response(T value, Response response) : base(value, response) { } + /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool HasValue => true; /// - public override T Value => Value; + public override T Value => base.Value!; /// /// Returns the value of this object. diff --git a/sdk/core/Azure.Core/src/RetryOptions.cs b/sdk/core/Azure.Core/src/RetryOptions.cs index 1baaedb4f00f..f3f84dcac588 100644 --- a/sdk/core/Azure.Core/src/RetryOptions.cs +++ b/sdk/core/Azure.Core/src/RetryOptions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ComponentModel; namespace Azure.Core { @@ -11,10 +12,22 @@ namespace Azure.Core /// public class RetryOptions { + internal const int DefaultMaxRetries = 3; + internal static readonly TimeSpan DefaultMaxDelay = TimeSpan.FromMinutes(1); + internal static readonly TimeSpan DefaultInitialDelay = TimeSpan.FromSeconds(0.8); + + private int _maxRetries = DefaultMaxRetries; + private TimeSpan _delay = DefaultInitialDelay; + private TimeSpan _maxDelay = DefaultMaxDelay; + private RetryMode _retryMode = RetryMode.Exponential; + private TimeSpan _networkTimeout = TimeSpan.FromSeconds(100); + + private bool _frozen; + /// /// Creates a new instance with default values. /// - internal RetryOptions() : this(ClientOptions.Default.Retry) + internal RetryOptions() { } @@ -37,29 +50,85 @@ internal RetryOptions(RetryOptions? retryOptions) /// /// The maximum number of retry attempts before giving up. /// - public int MaxRetries { get; set; } = 3; + public int MaxRetries + { + get => _maxRetries; + set + { + AssertNotFrozen(); + + _maxRetries = value; + } + } /// /// The delay between retry attempts for a fixed approach or the delay /// on which to base calculations for a backoff-based approach. /// If the service provides a Retry-After response header, the next retry will be delayed by the duration specified by the header value. /// - public TimeSpan Delay { get; set; } = TimeSpan.FromSeconds(0.8); + public TimeSpan Delay + { + get => _delay; + set + { + AssertNotFrozen(); + + _delay = value; + } + } /// /// The maximum permissible delay between retry attempts when the service does not provide a Retry-After response header. /// If the service provides a Retry-After response header, the next retry will be delayed by the duration specified by the header value. /// - public TimeSpan MaxDelay { get; set; } = TimeSpan.FromMinutes(1); + public TimeSpan MaxDelay + { + get => _maxDelay; + set + { + AssertNotFrozen(); + + _maxDelay = value; + } + } /// /// The approach to use for calculating retry delays. /// - public RetryMode Mode { get; set; } = RetryMode.Exponential; + public RetryMode Mode + { + get => _retryMode; + set + { + AssertNotFrozen(); + + _retryMode = value; + } + } /// /// The timeout applied to an individual network operations. /// - public TimeSpan NetworkTimeout { get; set; } = TimeSpan.FromSeconds(100); + [EditorBrowsable(EditorBrowsableState.Never)] + public TimeSpan NetworkTimeout + { + get => _networkTimeout; + set + { + AssertNotFrozen(); + + _networkTimeout = value; + } + } + + internal void Freeze() => _frozen = true; + + private void AssertNotFrozen() + { + if (_frozen) + { + throw new InvalidOperationException("Cannot change a ClientOptions instance after it has been used to create a client."); + } + } } } diff --git a/sdk/core/Azure.Core/src/StatusCodeClassifier.cs b/sdk/core/Azure.Core/src/StatusCodeClassifier.cs index 64869985d8d4..ed8715f044a8 100644 --- a/sdk/core/Azure.Core/src/StatusCodeClassifier.cs +++ b/sdk/core/Azure.Core/src/StatusCodeClassifier.cs @@ -2,9 +2,7 @@ // Licensed under the MIT License. using System; -using System.Diagnostics; - -#nullable enable +using System.ClientModel.Internal; namespace Azure.Core { @@ -14,20 +12,18 @@ namespace Azure.Core /// public class StatusCodeClassifier : ResponseClassifier { - // We need 10 ulongs to represent status codes 100 - 599. - private const int Length = 10; - private ulong[] _successCodes; + private BitVector640 _successCodes; internal ResponseClassificationHandler[]? Handlers { get; set; } /// - /// Creates a new instance of + /// Creates a new instance of . /// - /// The status codes that this classifier will consider - /// not to be errors. + /// The status codes that this classifier + /// will consider not to be errors. public StatusCodeClassifier(ReadOnlySpan successStatusCodes) { - _successCodes = new ulong[Length]; + _successCodes = new(); foreach (int statusCode in successStatusCodes) { @@ -35,70 +31,37 @@ public StatusCodeClassifier(ReadOnlySpan successStatusCodes) } } - private StatusCodeClassifier(ulong[] successCodes, ResponseClassificationHandler[]? handlers) + private StatusCodeClassifier(BitVector640 successCodes, ResponseClassificationHandler[]? handlers) { - Debug.Assert(successCodes?.Length == Length); - - _successCodes = successCodes!; + _successCodes = successCodes; Handlers = handlers; } /// public override bool IsErrorResponse(HttpMessage message) { - bool isError; - if (Handlers != null) { - foreach (var handler in Handlers) + foreach (ResponseClassificationHandler handler in Handlers) { - if (handler.TryClassify(message, out isError)) + if (handler.TryClassify(message, out bool isError)) { return isError; } } } - return !IsSuccessCode(message.Response.Status); + return !_successCodes[message.Response.Status]; } internal virtual StatusCodeClassifier Clone() - { - ulong[] successCodes = new ulong[Length]; - Array.Copy(_successCodes, successCodes, Length); - - return new StatusCodeClassifier(successCodes, Handlers); - } + => new(_successCodes, Handlers); internal void AddClassifier(int statusCode, bool isError) { Argument.AssertInRange(statusCode, 0, 639, nameof(statusCode)); - var index = statusCode >> 6; // divides by 64 - int bit = statusCode & 0b111111; // keeps the bits up to 63 - ulong mask = 1ul << bit; // shifts a 1 to the position of code - - ulong value = _successCodes[index]; - if (!isError) - { - value |= mask; - } - else - { - value &= ~mask; - } - - _successCodes[index] = value; - } - - private bool IsSuccessCode(int statusCode) - { - var index = statusCode >> 6; // divides by 64 - int bit = statusCode & 0b111111; // keeps the bits up to 63 - ulong mask = 1ul << bit; // shifts a 1 to the position of code - - ulong value = _successCodes[index]; - return (value & mask) != 0; + _successCodes[statusCode] = !isError; } } } diff --git a/sdk/core/Azure.Core/tests/FailedResponseExceptionTests.cs b/sdk/core/Azure.Core/tests/FailedResponseExceptionTests.cs index 4b58e0f1048b..626c7e1b771a 100644 --- a/sdk/core/Azure.Core/tests/FailedResponseExceptionTests.cs +++ b/sdk/core/Azure.Core/tests/FailedResponseExceptionTests.cs @@ -633,7 +633,7 @@ private class CustomParser : RequestFailedDetailsParser { public override bool TryParse(Response response, out ResponseError error, out IDictionary data) { - RequestFailedException.TryExtractErrorContent(response, out error, out data); + DefaultRequestFailedDetailsParser.TryParseDetails(response, out error, out data); data = response.Content.ToObjectFromJson>(); return true; } diff --git a/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs b/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs index 45c272f7064f..9a8a1e2d25ba 100644 --- a/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs +++ b/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs @@ -572,8 +572,7 @@ public async Task TimeoutsUnbufferedBodyReads() var buffer = new byte[10]; Assert.AreEqual(1, await responseContentStream.ReadAsync(buffer, 0, 1)); var exception = Assert.ThrowsAsync(async () => await responseContentStream.ReadAsync(buffer, 0, 10)); - Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.5. " + - "Network timeout can be adjusted in ClientOptions.Retry.NetworkTimeout.", exception.Message); + Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.5. ", exception.Message); testDoneTcs.Cancel(); } diff --git a/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs b/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs index f1b83631ef7a..3486de11775d 100644 --- a/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs +++ b/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs @@ -26,6 +26,23 @@ public void DoesNotThrowWhenValueIsAccessedWithValue() Assert.That(target.ToString(), Does.Contain("test")); } + [Test] + public void ThrowsWhenValueIsAccessedWithNoValue_2_0() + { + var target = new TestValueResponse2_0(new MockResponse(200)); + Assert.Throws(() => { var val = target.Value; }); + Assert.That(target.ToString(), Does.Contain("")); + } + + [Test] + public void DoesNotThrowWhenValueIsAccessedWithValue_2_0() + { + var target = new TestValueResponse2_0(new MockResponse(200), "test"); + Assert.AreEqual("test", target.Value); + Assert.That(target.ToString(), Does.Not.Contain("")); + Assert.That(target.ToString(), Does.Contain("test")); + } + private class TestValueResponse : NullableResponse { private readonly bool _hasValue; @@ -51,5 +68,23 @@ public TestValueResponse(Response response) public override Response GetRawResponse() => _response; } + + private class TestValueResponse2_0 : NullableResponse + { + private readonly bool _hasValue; + + public TestValueResponse2_0(Response response, T value) : base(value, response) + { + _hasValue = true; + } + + public TestValueResponse2_0(Response response) : base(default, response) + { + _hasValue = false; + } + public override bool HasValue => _hasValue; + + public override T Value => _hasValue ? base.Value : throw new Exception("has no value"); + } } } diff --git a/sdk/core/Azure.Core/tests/PipelineTestBase.cs b/sdk/core/Azure.Core/tests/PipelineTestBase.cs index d75ad0518e97..b964dc5daf58 100644 --- a/sdk/core/Azure.Core/tests/PipelineTestBase.cs +++ b/sdk/core/Azure.Core/tests/PipelineTestBase.cs @@ -18,7 +18,7 @@ public PipelineTestBase(bool isAsync) protected async Task ProcessAsync(HttpMessage message, HttpPipelineTransport transport, CancellationToken cancellationToken = default) { - message.CancellationToken = cancellationToken; + message.SetCancellationToken(cancellationToken); if (_isAsync) { await transport.ProcessAsync(message); @@ -32,7 +32,7 @@ protected async Task ProcessAsync(HttpMessage message, HttpPipelineTransport tra protected async Task ExecuteRequest(Request request, HttpPipelineTransport transport, CancellationToken cancellationToken = default) { var message = new HttpMessage(request, ResponseClassifier.Shared); - message.CancellationToken = cancellationToken; + message.SetCancellationToken(cancellationToken); if (_isAsync) { await transport.ProcessAsync(message); diff --git a/sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs b/sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs index 8ffd5e15e385..26fbc8045210 100644 --- a/sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs +++ b/sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs @@ -145,7 +145,8 @@ public async Task SetsReadTimeoutToProvidedValue() MockTransport mockTransport = new MockTransport(mockResponse); Response response = await SendGetRequest(mockTransport, new ResponseBodyPolicy(TimeSpan.FromMilliseconds(1234567)), bufferResponse: false); - Assert.IsInstanceOf(response.ContentStream); + //Assert.IsInstanceOf(response.ContentStream); + Assert.IsFalse(response.ContentStream.CanWrite); Assert.AreEqual(1234567, hangingStream.ReadTimeout); } @@ -206,7 +207,8 @@ public async Task CanOverrideDefaultNetworkTimeout_Stream() message.NetworkTimeout = TimeSpan.FromMilliseconds(30); }, new ResponseBodyPolicy(TimeSpan.MaxValue), bufferResponse: false); - Assert.IsInstanceOf(response.ContentStream); + //Assert.IsInstanceOf(response.ContentStream); + Assert.IsFalse(response.ContentStream.CanWrite); Assert.AreEqual(30, hangingStream.ReadTimeout); } diff --git a/sdk/core/Azure.Core/tests/RetryPolicyTestBase.cs b/sdk/core/Azure.Core/tests/RetryPolicyTestBase.cs index 838a01d13a7a..dbdf8fe265a2 100644 --- a/sdk/core/Azure.Core/tests/RetryPolicyTestBase.cs +++ b/sdk/core/Azure.Core/tests/RetryPolicyTestBase.cs @@ -11,7 +11,6 @@ using Azure.Core.Diagnostics; using Azure.Core.Pipeline; using Azure.Core.Samples; -using Azure.Core.Shared; using Azure.Core.TestFramework; using Moq; using NUnit.Framework; @@ -683,26 +682,26 @@ internal override Task WaitAsync(TimeSpan time, CancellationToken cancellationTo return DelayGate.WaitForRelease(time); } - protected internal override void OnRequestSent(HttpMessage message) + protected override void OnRequestSent(HttpMessage message) { OnRequestSentCalled = true; base.OnRequestSent(message); } - protected internal override ValueTask OnRequestSentAsync(HttpMessage message) + protected override ValueTask OnRequestSentAsync(HttpMessage message) { OnRequestSentCalled = true; return base.OnRequestSentAsync(message); } - protected internal override bool ShouldRetry(HttpMessage message, Exception exception) + protected override bool ShouldRetry(HttpMessage message, Exception exception) { LastException = exception; ShouldRetryCalled = true; return base.ShouldRetry(message, exception); } - protected internal override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) + protected override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) { LastException = exception; ShouldRetryCalled = true; diff --git a/sdk/core/Azure.Core/tests/common/Azure.Core.Tests.Common.csproj b/sdk/core/Azure.Core/tests/common/Azure.Core.Tests.Common.csproj index 47a4c21a2132..08f0257525c7 100644 --- a/sdk/core/Azure.Core/tests/common/Azure.Core.Tests.Common.csproj +++ b/sdk/core/Azure.Core/tests/common/Azure.Core.Tests.Common.csproj @@ -14,6 +14,7 @@ + From 1de8c311aa6a6a5a2bd0cd1ce268b0c8866cda0d Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 2 Feb 2024 17:03:08 -0800 Subject: [PATCH 02/47] updates --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 136 +++++++++--------- sdk/core/Azure.Core/api/Azure.Core.net472.cs | 136 +++++++++--------- sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 136 +++++++++--------- .../api/Azure.Core.netstandard2.0.cs | 136 +++++++++--------- .../tests/samples/GlobalTimeoutRetryPolicy.cs | 6 +- 5 files changed, 283 insertions(+), 267 deletions(-) diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index 49995b0e56e3..d5df397dda3d 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -208,49 +208,46 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public virtual new System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); @@ -264,7 +261,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -375,18 +374,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -481,23 +481,17 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -518,28 +512,34 @@ public static partial class MultipartResponse public static Azure.Response[] Parse(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } public static System.Threading.Tasks.Task ParseAsync(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); + protected override System.ClientModel.BinaryContent? GetContentCore() { throw null; } + protected override System.ClientModel.Primitives.PipelineRequestHeaders GetHeadersCore() { throw null; } + protected override string GetMethodCore() { throw null; } + protected override System.Uri GetUriCore() { throw null; } protected internal abstract bool RemoveHeader(string name); + protected override void SetContentCore(System.ClientModel.BinaryContent? content) { } protected internal virtual void SetHeader(string name, string value) { } + protected override void SetMethodCore(string method) { } + protected override void SetUriCore(System.Uri uri) { } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -549,13 +549,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -679,13 +676,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -716,6 +717,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1016,11 +1018,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1056,14 +1060,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index 49995b0e56e3..d5df397dda3d 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -208,49 +208,46 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public virtual new System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); @@ -264,7 +261,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -375,18 +374,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -481,23 +481,17 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -518,28 +512,34 @@ public static partial class MultipartResponse public static Azure.Response[] Parse(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } public static System.Threading.Tasks.Task ParseAsync(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); + protected override System.ClientModel.BinaryContent? GetContentCore() { throw null; } + protected override System.ClientModel.Primitives.PipelineRequestHeaders GetHeadersCore() { throw null; } + protected override string GetMethodCore() { throw null; } + protected override System.Uri GetUriCore() { throw null; } protected internal abstract bool RemoveHeader(string name); + protected override void SetContentCore(System.ClientModel.BinaryContent? content) { } protected internal virtual void SetHeader(string name, string value) { } + protected override void SetMethodCore(string method) { } + protected override void SetUriCore(System.Uri uri) { } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -549,13 +549,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -679,13 +676,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -716,6 +717,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1016,11 +1018,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1056,14 +1060,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index 16d3e7cb99ce..b5a657f013dc 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -208,49 +208,46 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public virtual new System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } protected internal abstract bool TryGetHeader(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value); protected internal abstract bool TryGetHeaderValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values); @@ -264,7 +261,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -375,18 +374,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -481,23 +481,17 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -518,28 +512,34 @@ public static partial class MultipartResponse public static Azure.Response[] Parse(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } public static System.Threading.Tasks.Task ParseAsync(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); + protected override System.ClientModel.BinaryContent? GetContentCore() { throw null; } + protected override System.ClientModel.Primitives.PipelineRequestHeaders GetHeadersCore() { throw null; } + protected override string GetMethodCore() { throw null; } + protected override System.Uri GetUriCore() { throw null; } protected internal abstract bool RemoveHeader(string name); + protected override void SetContentCore(System.ClientModel.BinaryContent? content) { } protected internal virtual void SetHeader(string name, string value) { } + protected override void SetMethodCore(string method) { } + protected override void SetUriCore(System.Uri uri) { } protected internal abstract bool TryGetHeader(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value); protected internal abstract bool TryGetHeaderValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -552,13 +552,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -682,13 +679,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -719,6 +720,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1019,11 +1021,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1060,14 +1064,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index 49995b0e56e3..d5df397dda3d 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -208,49 +208,46 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public virtual new System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); @@ -264,7 +261,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -375,18 +374,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -481,23 +481,17 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -518,28 +512,34 @@ public static partial class MultipartResponse public static Azure.Response[] Parse(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } public static System.Threading.Tasks.Task ParseAsync(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); + protected override System.ClientModel.BinaryContent? GetContentCore() { throw null; } + protected override System.ClientModel.Primitives.PipelineRequestHeaders GetHeadersCore() { throw null; } + protected override string GetMethodCore() { throw null; } + protected override System.Uri GetUriCore() { throw null; } protected internal abstract bool RemoveHeader(string name); + protected override void SetContentCore(System.ClientModel.BinaryContent? content) { } protected internal virtual void SetHeader(string name, string value) { } + protected override void SetMethodCore(string method) { } + protected override void SetUriCore(System.Uri uri) { } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -549,13 +549,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -679,13 +676,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -716,6 +717,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1016,11 +1018,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1056,14 +1060,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/tests/samples/GlobalTimeoutRetryPolicy.cs b/sdk/core/Azure.Core/tests/samples/GlobalTimeoutRetryPolicy.cs index f3ab311f63e0..c0ae8f0e8340 100644 --- a/sdk/core/Azure.Core/tests/samples/GlobalTimeoutRetryPolicy.cs +++ b/sdk/core/Azure.Core/tests/samples/GlobalTimeoutRetryPolicy.cs @@ -17,11 +17,11 @@ public GlobalTimeoutRetryPolicy(int maxRetries, DelayStrategy delayStrategy, Tim _timeout = timeout; } - protected internal override bool ShouldRetry(HttpMessage message, Exception exception) + protected override bool ShouldRetry(HttpMessage message, Exception exception) { return ShouldRetryInternalAsync(message, exception, false).EnsureCompleted(); } - protected internal override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) + protected override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) { return ShouldRetryInternalAsync(message, exception, true); } @@ -38,4 +38,4 @@ private ValueTask ShouldRetryInternalAsync(HttpMessage message, Exception } } #endregion -} \ No newline at end of file +} From 2748b05f78334c6d8b209f5e8054aab618edd35f Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 2 Feb 2024 17:09:16 -0800 Subject: [PATCH 03/47] updates --- sdk/core/Azure.Core/samples/Configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/core/Azure.Core/samples/Configuration.md b/sdk/core/Azure.Core/samples/Configuration.md index 75ba94b58ed8..1aa9263af641 100644 --- a/sdk/core/Azure.Core/samples/Configuration.md +++ b/sdk/core/Azure.Core/samples/Configuration.md @@ -36,11 +36,11 @@ internal class GlobalTimeoutRetryPolicy : RetryPolicy _timeout = timeout; } - protected internal override bool ShouldRetry(HttpMessage message, Exception exception) + protected override bool ShouldRetry(HttpMessage message, Exception exception) { return ShouldRetryInternalAsync(message, exception, false).EnsureCompleted(); } - protected internal override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) + protected override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) { return ShouldRetryInternalAsync(message, exception, true); } From 35f2e7f79f1fc3d9696a8291f94213522c567e3c Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 2 Feb 2024 17:16:49 -0800 Subject: [PATCH 04/47] nits --- sdk/core/Azure.Core/src/NullableResponseOfT.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sdk/core/Azure.Core/src/NullableResponseOfT.cs b/sdk/core/Azure.Core/src/NullableResponseOfT.cs index 459f94897fba..1ddad9f45289 100644 --- a/sdk/core/Azure.Core/src/NullableResponseOfT.cs +++ b/sdk/core/Azure.Core/src/NullableResponseOfT.cs @@ -14,9 +14,10 @@ namespace Azure public abstract class NullableResponse : ClientResult #pragma warning restore SA1649 // File name should match first type name { + private const string NoValue = ""; + private readonly T? _value; - private const string NoValue = ""; internal static Response DefaultResponse = new Response.AzureCoreDefaultResponse(); /// @@ -44,19 +45,11 @@ protected NullableResponse(T? value, Response response) _value = value; } - ///// - ///// Gets the value returned by the service. Accessing this property will throw if is false. - ///// - //public virtual T? Value => _value; - /// /// Gets a value indicating whether the current instance has a non-null value. /// public virtual bool HasValue => _value != null; - private static Response ReplaceWithDefaultIfNull(Response? response) - => response ?? DefaultResponse; - /// /// Returns the HTTP response returned by the service. /// @@ -74,5 +67,8 @@ private static Response ReplaceWithDefaultIfNull(Response? response) /// public override string ToString() => $"Status: {GetRawResponse()?.Status}, Value: {(HasValue ? Value : NoValue)}"; + + private static Response ReplaceWithDefaultIfNull(Response? response) + => response ?? DefaultResponse; } } From af87fe090050acdf30b114d700704afc9fec7f53 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 2 Feb 2024 17:20:30 -0800 Subject: [PATCH 05/47] nits --- sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs index c92620d445a8..4bb679772725 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs @@ -3,7 +3,6 @@ using System; using System.ClientModel; -using System.ClientModel.Primitives; using System.Diagnostics; using System.Net; using System.Net.Http; @@ -24,8 +23,7 @@ public partial class HttpClientTransport : HttpPipelineTransport, IDisposable /// public static readonly HttpClientTransport Shared = new HttpClientTransport(); - // The transport's private HttpClient has been made internal because it is used by tests. - // TODO: move these tests into System.Rest? - can we make it private when we do? + // The transport's private HttpClient is internal because it is used by tests. internal HttpClient Client { get; } private readonly AzureCoreHttpPipelineTransport _transport; @@ -41,7 +39,8 @@ public HttpClientTransport() : this(CreateDefaultClient()) /// Creates a new instance of using the provided client instance. /// /// The instance of to use. - public HttpClientTransport(HttpMessageHandler messageHandler) : this(new HttpClient(messageHandler)) + public HttpClientTransport(HttpMessageHandler messageHandler) + : this(new HttpClient(messageHandler)) { } From 2644b26fed435e42f79dad3b809b1177c09a9811 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 2 Feb 2024 17:30:31 -0800 Subject: [PATCH 06/47] nits --- sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs index 04c1a25871fa..221270684e8a 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs @@ -109,7 +109,7 @@ public HttpMessage CreateMessage(RequestContext? context) /// The message. public HttpMessage CreateMessage(RequestContext? context, ResponseClassifier? classifier = default) { - HttpMessage message = new HttpMessage(CreateRequest(), classifier ?? ResponseClassifier); + HttpMessage message = new(CreateRequest(), classifier ?? ResponseClassifier); if (context != null) { @@ -174,10 +174,11 @@ public void Send(HttpMessage message, CancellationToken cancellationToken) if (message.Policies == null || message.Policies.Count == 0) { _pipeline.Span[0].Process(message, _pipeline.Slice(1)); - return; } - - Send(message); + else + { + Send(message); + } } private void Send(HttpMessage message) From f5c09a15b92cefa051f316605ae0a4dd55420789 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 2 Feb 2024 17:36:07 -0800 Subject: [PATCH 07/47] nits --- sdk/core/Azure.Core/src/RequestUriBuilder.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/core/Azure.Core/src/RequestUriBuilder.cs b/sdk/core/Azure.Core/src/RequestUriBuilder.cs index 6b04523e44ab..c153c9f6caa2 100644 --- a/sdk/core/Azure.Core/src/RequestUriBuilder.cs +++ b/sdk/core/Azure.Core/src/RequestUriBuilder.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.IO; using System.Text; namespace Azure.Core @@ -28,8 +29,6 @@ public class RequestUriBuilder private string? _scheme; - internal bool IsValidUri => Scheme != null && Host != null; - /// /// Gets or sets the scheme name of the URI. /// From 28be90bc1e0b12a5941a2ae5e55f2889aa80a534 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 09:14:35 -0800 Subject: [PATCH 08/47] nits --- sdk/core/Azure.Core/src/Response.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/core/Azure.Core/src/Response.cs b/sdk/core/Azure.Core/src/Response.cs index 6efa478996bb..915394de8939 100644 --- a/sdk/core/Azure.Core/src/Response.cs +++ b/sdk/core/Azure.Core/src/Response.cs @@ -26,7 +26,6 @@ public abstract class Response : PipelineResponse /// /// Get the HTTP response headers. /// - // TODO: is is possible to not new-slot this? public new virtual ResponseHeaders Headers => new ResponseHeaders(this); /// From 1d5be209bd5f489f7eafee24f00ca8f1ebe7ac0e Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 16:26:34 -0800 Subject: [PATCH 09/47] updates --- .../Azure.Core/src/Internal/ValueResponse.cs | 20 -- .../Pipeline/Internal/ReadTimeoutStream.cs | 186 ------------------ .../tests/ReadTimeoutStreamTests.cs | 111 ----------- 3 files changed, 317 deletions(-) delete mode 100644 sdk/core/Azure.Core/src/Internal/ValueResponse.cs delete mode 100644 sdk/core/Azure.Core/src/Pipeline/Internal/ReadTimeoutStream.cs delete mode 100644 sdk/core/Azure.Core/tests/ReadTimeoutStreamTests.cs diff --git a/sdk/core/Azure.Core/src/Internal/ValueResponse.cs b/sdk/core/Azure.Core/src/Internal/ValueResponse.cs deleted file mode 100644 index b6db85a79089..000000000000 --- a/sdk/core/Azure.Core/src/Internal/ValueResponse.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -namespace Azure -{ - internal class ValueResponse : Response - { - private readonly Response _response; - - public ValueResponse(Response response, T value) - { - _response = response; - Value = value; - } - - public override T Value { get; } - - public override Response GetRawResponse() => _response; - } -} diff --git a/sdk/core/Azure.Core/src/Pipeline/Internal/ReadTimeoutStream.cs b/sdk/core/Azure.Core/src/Pipeline/Internal/ReadTimeoutStream.cs deleted file mode 100644 index 0bc6dc68b8fc..000000000000 --- a/sdk/core/Azure.Core/src/Pipeline/Internal/ReadTimeoutStream.cs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Azure.Core.Pipeline -{ - /// - /// Read-only Stream that will throw a if it has to wait longer than a configurable timeout to read more data - /// - internal class ReadTimeoutStream : ReadOnlyStream - { - private readonly Stream _stream; - private TimeSpan _readTimeout; - private CancellationTokenSource _cancellationTokenSource = null!; - - public ReadTimeoutStream(Stream stream, TimeSpan readTimeout) - { - _stream = stream; - _readTimeout = readTimeout; - UpdateReadTimeout(); - InitializeTokenSource(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - var source = StartTimeout(default, out bool dispose); - try - { - return _stream.Read(buffer, offset, count); - } - // We dispose stream on timeout so catch and check if cancellation token was cancelled - catch (IOException ex) - { - ResponseBodyPolicy.ThrowIfCancellationRequestedOrTimeout(default, source.Token, ex, _readTimeout); - throw; - } - // We dispose stream on timeout so catch and check if cancellation token was cancelled - catch (ObjectDisposedException ex) - { - ResponseBodyPolicy.ThrowIfCancellationRequestedOrTimeout(default, source.Token, ex, _readTimeout); - throw; - } - catch (OperationCanceledException ex) - { - ResponseBodyPolicy.ThrowIfCancellationRequestedOrTimeout(default, source.Token, ex, _readTimeout); - throw; - } - finally - { - StopTimeout(source, dispose); - } - } - - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - var source = StartTimeout(cancellationToken, out bool dispose); - try - { -#pragma warning disable CA1835 // ReadAsync(Memory<>) overload is not available in all targets - return await _stream.ReadAsync(buffer, offset, count, source.Token).ConfigureAwait(false); -#pragma warning restore // ReadAsync(Memory<>) overload is not available in all targets - } - // We dispose stream on timeout so catch and check if cancellation token was cancelled - catch (IOException ex) - { - ResponseBodyPolicy.ThrowIfCancellationRequestedOrTimeout(cancellationToken, source.Token, ex, _readTimeout); - throw; - } - // We dispose stream on timeout so catch and check if cancellation token was cancelled - catch (ObjectDisposedException ex) - { - ResponseBodyPolicy.ThrowIfCancellationRequestedOrTimeout(cancellationToken, source.Token, ex, _readTimeout); - throw; - } - catch (OperationCanceledException ex) - { - ResponseBodyPolicy.ThrowIfCancellationRequestedOrTimeout(cancellationToken, source.Token, ex, _readTimeout); - throw; - } - finally - { - StopTimeout(source, dispose); - } - } - - private CancellationTokenSource StartTimeout(CancellationToken additionalToken, out bool dispose) - { - if (_cancellationTokenSource.IsCancellationRequested) - { - InitializeTokenSource(); - } - - CancellationTokenSource source; - if (additionalToken.CanBeCanceled) - { - source = CancellationTokenSource.CreateLinkedTokenSource(additionalToken, _cancellationTokenSource.Token); - dispose = true; - } - else - { - source = _cancellationTokenSource; - dispose = false; - } - - _cancellationTokenSource.CancelAfter(_readTimeout); - - return source; - } - - private void InitializeTokenSource() - { - _cancellationTokenSource = new CancellationTokenSource(); - _cancellationTokenSource.Token.Register(static state => ((ReadTimeoutStream)state!).DisposeStream(), this); - } - - private void DisposeStream() - { - _stream.Dispose(); - } - - private void StopTimeout(CancellationTokenSource source, bool dispose) - { - _cancellationTokenSource.CancelAfter(Timeout.InfiniteTimeSpan); - if (dispose) - { - source.Dispose(); - } - } - - public override long Seek(long offset, SeekOrigin origin) - { - return _stream.Seek(offset, origin); - } - - public override bool CanRead => _stream.CanRead; - public override bool CanSeek => _stream.CanSeek; - public override long Length => _stream.Length; - - public override long Position - { - get => _stream.Position; - set => _stream.Position = value; - } - - public override int ReadTimeout - { - get => (int) _readTimeout.TotalMilliseconds; - set - { - _readTimeout = TimeSpan.FromMilliseconds(value); - UpdateReadTimeout(); - } - } - - private void UpdateReadTimeout() - { - try - { - if (_stream.CanTimeout) - { - _stream.ReadTimeout = (int) _readTimeout.TotalMilliseconds; - } - } - catch - { - // ignore - } - } - - public override void Close() - { - _stream.Close(); - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _stream.Dispose(); - _cancellationTokenSource.Dispose(); - } - } -} diff --git a/sdk/core/Azure.Core/tests/ReadTimeoutStreamTests.cs b/sdk/core/Azure.Core/tests/ReadTimeoutStreamTests.cs deleted file mode 100644 index e7ab2f7ac39d..000000000000 --- a/sdk/core/Azure.Core/tests/ReadTimeoutStreamTests.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using Azure.Core.Pipeline; -using NUnit.Framework; - -namespace Azure.Core.Tests -{ - public class ReadTimeoutStreamTests - { - private readonly byte[] _buffer = new byte[1]; - private readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(0.1); - - [Test] - public void StreamIsDisposedForTimeoutInSyncRead() - { - var testStream = new TestStream(); - var timeoutStream = new ReadTimeoutStream(testStream, _defaultTimeout); - - Assert.Throws(() => timeoutStream.Read(_buffer, 0, 1)); - } - - [Test] - public void StreamIsDisposedForTimeoutInAsyncReadWhenTokenIsIgnored() - { - var testStream = new TestStream(true); - var timeoutStream = new ReadTimeoutStream(testStream, _defaultTimeout); - - Assert.ThrowsAsync(() => timeoutStream.ReadAsync(_buffer, 0, 1)); - } - - [Test] - public void ReadIsCancelledOnTimeout() - { - var testStream = new TestStream(true); - var timeoutStream = new ReadTimeoutStream(testStream, _defaultTimeout); - - Assert.ThrowsAsync(() => timeoutStream.ReadAsync(_buffer, 0, 1)); - } - - [Test] - public void ReadIsCancelledOnTimeoutWithAdditionalToken() - { - var testStream = new TestStream(true); - var timeoutStream = new ReadTimeoutStream(testStream, _defaultTimeout); - var cancellationTokenSource = new CancellationTokenSource(); - cancellationTokenSource.CancelAfter(1000000); - - var cancellationToken = cancellationTokenSource.Token; - - Assert.ThrowsAsync(() => timeoutStream.ReadAsync(_buffer, 0, 1, cancellationToken)); - } - - [Test] - public void DisposeDisposesInnerStream() - { - var testStream = new TestStream(true); - var timeoutStream = new ReadTimeoutStream(testStream, _defaultTimeout); - timeoutStream.Dispose(); - - Assert.True(testStream.IsDisposed); - } - - private class TestStream : ReadOnlyStream - { - private readonly bool _ignoreToken; - private TaskCompletionSource _disposeTCS; - - public TestStream(bool ignoreToken = false) - { - _ignoreToken = ignoreToken; - _disposeTCS = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - } - - public bool IsDisposed { get; set; } - - protected override void Dispose(bool disposing) - { - IsDisposed = true; - _disposeTCS.SetException(new ObjectDisposedException(nameof(TestStream))); - base.Dispose(disposing); - } - - public override int Read(byte[] buffer, int offset, int count) - { - _disposeTCS.Task.GetAwaiter().GetResult(); - return 0; - } - - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - await _disposeTCS.Task.AwaitWithCancellation(_ignoreToken ? default : cancellationToken); - return 0; - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new System.NotImplementedException(); - } - - public override bool CanRead { get; } - public override bool CanSeek { get; } - public override long Length { get; } - public override long Position { get; set; } - } - } -} \ No newline at end of file From 7689d558a395c04bedb09bdde4831e8672de6340 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 16:40:42 -0800 Subject: [PATCH 10/47] updates --- sdk/core/Azure.Core/src/HttpMessage.cs | 12 +++++++++ .../src/Pipeline/RetryPolicy.AzurePolicy.cs | 26 ++++++------------- sdk/core/Azure.Core/src/ResponseClassifier.cs | 15 ++--------- .../src/Convenience/ClientResultOfT.cs | 3 +++ 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/sdk/core/Azure.Core/src/HttpMessage.cs b/sdk/core/Azure.Core/src/HttpMessage.cs index 467b5dafa317..bcf04d0700ce 100644 --- a/sdk/core/Azure.Core/src/HttpMessage.cs +++ b/sdk/core/Azure.Core/src/HttpMessage.cs @@ -102,7 +102,18 @@ internal void ApplyRequestContext(RequestContext context, ResponseClassifier? cl internal List<(HttpPipelinePosition Position, HttpPipelinePolicy Policy)>? Policies { get; set; } + internal static HttpMessage AssertHttpMessage(PipelineMessage message) + { + if (message is not HttpMessage httpMessage) + { + throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'."); + } + + return httpMessage; + } + #region Message Properties + /// /// Gets a property that modifies the pipeline behavior. Please refer to individual policies documentation on what properties it supports. /// @@ -144,6 +155,7 @@ public void SetProperty(string name, object value) /// Exists as a private key entry into the property bag for stashing string keyed entries in the Type keyed dictionary. /// private class MessagePropertyKey { } + #endregion /// diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs index 06b6a1ea95c5..c6f724a2f60f 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs @@ -32,19 +32,19 @@ protected override void OnSendingRequest(PipelineMessage message) { _beforeProcess = Stopwatch.GetTimestamp(); - _pipelinePolicy.OnSendingRequest(AssertHttpMessage(message)); + _pipelinePolicy.OnSendingRequest(HttpMessage.AssertHttpMessage(message)); } protected override async ValueTask OnSendingRequestAsync(PipelineMessage message) { _beforeProcess = Stopwatch.GetTimestamp(); - await _pipelinePolicy.OnSendingRequestAsync(AssertHttpMessage(message)).ConfigureAwait(false); + await _pipelinePolicy.OnSendingRequestAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); } protected override void OnRequestSent(PipelineMessage message) { - _pipelinePolicy.OnRequestSent(AssertHttpMessage(message)); + _pipelinePolicy.OnRequestSent(HttpMessage.AssertHttpMessage(message)); _afterProcess = Stopwatch.GetTimestamp(); _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; @@ -52,21 +52,21 @@ protected override void OnRequestSent(PipelineMessage message) protected override async ValueTask OnRequestSentAsync(PipelineMessage message) { - await _pipelinePolicy.OnRequestSentAsync(AssertHttpMessage(message)).ConfigureAwait(false); + await _pipelinePolicy.OnRequestSentAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); _afterProcess = Stopwatch.GetTimestamp(); _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; } protected override bool ShouldRetry(PipelineMessage message, Exception? exception) - => _pipelinePolicy.ShouldRetry(AssertHttpMessage(message), exception); + => _pipelinePolicy.ShouldRetry(HttpMessage.AssertHttpMessage(message), exception); protected override async ValueTask ShouldRetryAsync(PipelineMessage message, Exception? exception) - => await _pipelinePolicy.ShouldRetryAsync(AssertHttpMessage(message), exception).ConfigureAwait(false); + => await _pipelinePolicy.ShouldRetryAsync(HttpMessage.AssertHttpMessage(message), exception).ConfigureAwait(false); protected override void OnTryComplete(PipelineMessage message) { - HttpMessage httpMessage = AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); httpMessage.RetryNumber++; AzureCoreEventSource.Singleton.RequestRetrying(httpMessage.Request.ClientRequestId, httpMessage.RetryNumber, _elapsedTime); @@ -79,7 +79,7 @@ protected override void OnTryComplete(PipelineMessage message) protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) { - HttpMessage httpMessage = AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); Debug.Assert(tryCount == httpMessage.RetryNumber); @@ -92,15 +92,5 @@ protected override async Task WaitAsync(TimeSpan time, CancellationToken cancell protected override void Wait(TimeSpan time, CancellationToken cancellationToken) => _pipelinePolicy.Wait(time, cancellationToken); - - private static HttpMessage AssertHttpMessage(PipelineMessage message) - { - if (message is not HttpMessage httpMessage) - { - throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'."); - } - - return httpMessage; - } } } diff --git a/sdk/core/Azure.Core/src/ResponseClassifier.cs b/sdk/core/Azure.Core/src/ResponseClassifier.cs index 8986234a22b2..a9ee3cb1358f 100644 --- a/sdk/core/Azure.Core/src/ResponseClassifier.cs +++ b/sdk/core/Azure.Core/src/ResponseClassifier.cs @@ -76,7 +76,7 @@ public virtual bool IsErrorResponse(HttpMessage message) // on a subtype of ResponseClassifier. public sealed override bool TryClassify(PipelineMessage message, out bool isError) { - HttpMessage httpMessage = AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); isError = IsErrorResponse(httpMessage); @@ -96,7 +96,7 @@ public sealed override bool TryClassify(PipelineMessage message, out bool isErro // on a subtype of ResponseClassifier. public sealed override bool TryClassify(PipelineMessage message, Exception? exception, out bool isRetriable) { - HttpMessage httpMessage = AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); isRetriable = exception is null ? IsRetriableResponse(httpMessage) : @@ -104,16 +104,5 @@ public sealed override bool TryClassify(PipelineMessage message, Exception? exce return true; } - - // TODO: remove duplication with this and other instances - private static HttpMessage AssertHttpMessage(PipelineMessage message) - { - if (message is not HttpMessage httpMessage) - { - throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'."); - } - - return httpMessage; - } } } diff --git a/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs b/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs index 48e934f0de9b..82685f517619 100644 --- a/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs +++ b/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs @@ -13,5 +13,8 @@ protected internal ClientResult(T value, PipelineResponse response) Value = value; } + /// + /// TBD. Needed for inheritdoc. + /// public virtual T Value { get; } } From 9f071bb3b54e18aa25f2a42ec5da6c5ed69fffeb Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 17:03:57 -0800 Subject: [PATCH 11/47] updates --- sdk/core/Azure.Core/src/RequestContent.cs | 6 +- .../tests/HttpPipelineMessageTest.cs | 2 + .../src/Azure.DigitalTwins.Core.csproj | 4 +- .../src/DigitalTwinsClient.cs | 97 ++++++++++--------- .../src/Azure.Data.Tables.csproj | 2 +- .../Azure.Data.Tables/src/TableClient.cs | 7 +- .../src/TableServiceClient.cs | 5 +- 7 files changed, 64 insertions(+), 59 deletions(-) rename sdk/{identity/Azure.Identity => core/Azure.Core}/tests/HttpPipelineMessageTest.cs (99%) diff --git a/sdk/core/Azure.Core/src/RequestContent.cs b/sdk/core/Azure.Core/src/RequestContent.cs index 0cd1a3db94cf..657f5042bb59 100644 --- a/sdk/core/Azure.Core/src/RequestContent.cs +++ b/sdk/core/Azure.Core/src/RequestContent.cs @@ -92,7 +92,7 @@ public abstract class RequestContent : BinaryContent /// The to use. /// An instance of that wraps a a . public static new RequestContent Create(T model, ModelReaderWriterOptions? options = default) where T : IPersistableModel - => new AzureInputContent(BinaryContent.Create(model, options ?? ModelWriteWireOptions)); + => new AzureBinaryContent(BinaryContent.Create(model, options ?? ModelWriteWireOptions)); /// /// Creates an instance of that wraps a serialized version of an object. @@ -152,11 +152,11 @@ public static RequestContent Create(object serializable, JsonPropertyNames prope /// The to use. public static implicit operator RequestContent(DynamicData content) => Create(content); - private sealed class AzureInputContent : RequestContent + private sealed class AzureBinaryContent : RequestContent { private readonly BinaryContent _content; - public AzureInputContent(BinaryContent content) + public AzureBinaryContent(BinaryContent content) { _content = content; } diff --git a/sdk/identity/Azure.Identity/tests/HttpPipelineMessageTest.cs b/sdk/core/Azure.Core/tests/HttpPipelineMessageTest.cs similarity index 99% rename from sdk/identity/Azure.Identity/tests/HttpPipelineMessageTest.cs rename to sdk/core/Azure.Core/tests/HttpPipelineMessageTest.cs index 7fd9387161db..be3cbd411af2 100644 --- a/sdk/identity/Azure.Identity/tests/HttpPipelineMessageTest.cs +++ b/sdk/core/Azure.Core/tests/HttpPipelineMessageTest.cs @@ -20,6 +20,7 @@ public void DisposeNoopsForNullResponse() var requestMock = new Mock(); HttpMessage message = new HttpMessage(requestMock.Object, _classifier); message.Dispose(); + requestMock.Verify(r => r.Dispose(), Times.Once); } @@ -31,6 +32,7 @@ public void DisposingMessageDisposesTheRequestAndResponse() HttpMessage message = new HttpMessage(requestMock.Object, _classifier); message.Response = responseMock.Object; message.Dispose(); + requestMock.Verify(r => r.Dispose(), Times.Once); responseMock.Verify(r => r.Dispose(), Times.Once); } diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj index c9ebbc42a035..461c6404cbd0 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj @@ -19,7 +19,6 @@ - @@ -32,5 +31,8 @@ Shared\Azure.Core + + + diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs index 73eb1aaff8d4..4cf3bbdb7b2f 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs @@ -9,6 +9,7 @@ using System.Threading; using System.Threading.Tasks; using Azure.Core; +using System.ClientModel; using Azure.Core.Pipeline; using Azure.Core.Serialization; using Azure.DigitalTwins.Core.Models; @@ -137,7 +138,7 @@ protected DigitalTwinsClient() /// The deserialized application/json digital twin and the HTTP response . /// The type to deserialize the digital twin to. /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -203,7 +204,7 @@ public virtual async Task> GetDigitalTwinAsync(string digitalTwin /// The deserialized application/json digital twin and the HTTP response . /// The type to deserialize the digital twin to. /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -256,7 +257,7 @@ public virtual Response GetDigitalTwin(string digitalTwinId, CancellationT /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -345,7 +346,7 @@ public virtual async Task> CreateOrReplaceDigitalTwinAsync( /// /// The exception is thrown when or is null. /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// public virtual Response CreateOrReplaceDigitalTwin( string digitalTwinId, @@ -391,7 +392,7 @@ public virtual Response CreateOrReplaceDigitalTwin( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -441,7 +442,7 @@ public virtual async Task DeleteDigitalTwinAsync(string digitalTwinId, /// /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -478,7 +479,7 @@ public virtual Response DeleteDigitalTwin(string digitalTwinId, ETag? ifMatch = /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -519,7 +520,7 @@ public virtual async Task UpdateDigitalTwinAsync(string digitalTwinId, /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -558,7 +559,7 @@ public virtual Response UpdateDigitalTwin(string digitalTwinId, JsonPatchDocumen /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -609,7 +610,7 @@ public virtual async Task> GetComponentAsync(string digitalTwinId /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -652,7 +653,7 @@ public virtual Response GetComponent(string digitalTwinId, string componen /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// @@ -719,7 +720,7 @@ public virtual async Task UpdateComponentAsync( /// /// The exception is thrown when or is null. /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// public virtual Response UpdateComponent( @@ -767,7 +768,7 @@ public virtual Response UpdateComponent( /// /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -860,7 +861,7 @@ async Task> NextPageFunc(string nextLink, int? pageSizeHint) /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -933,7 +934,7 @@ Page NextPageFunc(string nextLink, int? pageSizeHint) /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -1012,7 +1013,7 @@ async Task> NextPageFunc(string nextLink, int? pageSi /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -1081,7 +1082,7 @@ Page NextPageFunc(string nextLink, int? pageSizeHint) /// /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -1138,7 +1139,7 @@ public virtual async Task> GetRelationshipAsync( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -1186,7 +1187,7 @@ public virtual Response GetRelationship( /// /// The exception is thrown when or is null. /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// public virtual async Task DeleteRelationshipAsync(string digitalTwinId, string relationshipId, ETag? ifMatch = null, CancellationToken cancellationToken = default) @@ -1222,7 +1223,7 @@ public virtual async Task DeleteRelationshipAsync(string digitalTwinId /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -1279,7 +1280,7 @@ public virtual Response DeleteRelationship(string digitalTwinId, string relation /// /// The type to deserialize the relationship to. /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -1374,7 +1375,7 @@ public virtual async Task> CreateOrReplaceRelationshipAsync( /// /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -1428,7 +1429,7 @@ public virtual Response CreateOrReplaceRelationship( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -1481,7 +1482,7 @@ public virtual async Task UpdateRelationshipAsync( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -1524,7 +1525,7 @@ public virtual Response UpdateRelationship( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// @@ -1617,7 +1618,7 @@ async Task> NextPageFunc(string nextLink, int? pageS /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// public virtual Pageable GetModels(GetModelsOptions options = null, CancellationToken cancellationToken = default) @@ -1680,7 +1681,7 @@ Page NextPageFunc(string nextLink, int? pageSizeHint) /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -1720,7 +1721,7 @@ public virtual async Task> GetModelAsync(string /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -1761,7 +1762,7 @@ public virtual Response GetModel(string modelId, Cancella /// /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -1816,7 +1817,7 @@ public virtual async Task DecommissionModelAsync(string modelId, Cance /// /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -1846,7 +1847,7 @@ public virtual Response DecommissionModel(string modelId, CancellationToken canc /// The cancellation token. /// The created models and the HTTP response . /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// @@ -1905,7 +1906,7 @@ public virtual async Task> CreateModelsAsync(I /// Understand twin models in Azure Digital Twins. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// public virtual Response CreateModels(IEnumerable dtdlModels, CancellationToken cancellationToken = default) @@ -1945,7 +1946,7 @@ public virtual Response CreateModels(IEnumerable /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2001,7 +2002,7 @@ public virtual async Task DeleteModelAsync(string modelId, Cancellatio /// /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2395,7 +2396,7 @@ public virtual Response CancelImportJob(string jobId, CancellationTok /// Query limitations. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// @@ -2514,7 +2515,7 @@ async Task> NextPageFunc(string nextLink, int? pageSizeHint) /// Query limitations. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// A basic query for all digital twins: SELECT * FROM digitalTwins. @@ -2613,7 +2614,7 @@ Page NextPageFunc(string nextLink, int? pageSizeHint) /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// @@ -2698,7 +2699,7 @@ async Task> NextPageFunc(string nextLink, int? page /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// public virtual Pageable GetEventRoutes(CancellationToken cancellationToken = default) @@ -2772,7 +2773,7 @@ Page NextPageFunc(string nextLink, int? pageSizeHint) /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2805,7 +2806,7 @@ public virtual async Task> GetEventRouteAsync(s /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2840,7 +2841,7 @@ public virtual Response GetEventRoute(string eventRouteI /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2884,7 +2885,7 @@ public virtual async Task CreateOrReplaceEventRouteAsync(string eventR /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2917,7 +2918,7 @@ public virtual Response CreateOrReplaceEventRoute(string eventRouteId, DigitalTw /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2956,7 +2957,7 @@ public virtual async Task DeleteEventRouteAsync(string eventRouteId, C /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when is null. @@ -2994,7 +2995,7 @@ public virtual Response DeleteEventRoute(string eventRouteId, CancellationToken /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -3059,7 +3060,7 @@ public virtual async Task PublishTelemetryAsync( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or is null. @@ -3116,7 +3117,7 @@ public virtual Response PublishTelemetry( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or or is null. @@ -3192,7 +3193,7 @@ public virtual async Task PublishComponentTelemetryAsync( /// For more samples, see our repo samples. /// /// - /// The exception that captures the errors from the service. Check the and properties for more details. + /// The exception that captures the errors from the service. Check the and properties for more details. /// /// /// The exception is thrown when or or is null. diff --git a/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj b/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj index 5ed703520c24..c91e8223b536 100644 --- a/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj +++ b/sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj @@ -12,7 +12,7 @@ true - + diff --git a/sdk/tables/Azure.Data.Tables/src/TableClient.cs b/sdk/tables/Azure.Data.Tables/src/TableClient.cs index 5bc5d7ad0f8e..908bc2ef4dd6 100644 --- a/sdk/tables/Azure.Data.Tables/src/TableClient.cs +++ b/sdk/tables/Azure.Data.Tables/src/TableClient.cs @@ -2,9 +2,8 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; -using System.Data; -using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Net; @@ -478,7 +477,7 @@ public virtual async Task> CreateAsync(CancellationToken can /// /// A controlling the request lifetime. /// The server returned an error. See for details returned from the server. - /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. + /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. public virtual Response CreateIfNotExists(CancellationToken cancellationToken = default) { using DiagnosticScope scope = _diagnostics.CreateScope($"{nameof(TableClient)}.{nameof(CreateIfNotExists)}"); @@ -517,7 +516,7 @@ public virtual Response CreateIfNotExists(CancellationToken cancellat /// /// A controlling the request lifetime. /// The server returned an error. See for details returned from the server. - /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. + /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. public virtual async Task> CreateIfNotExistsAsync(CancellationToken cancellationToken = default) { using DiagnosticScope scope = _diagnostics.CreateScope($"{nameof(TableClient)}.{nameof(CreateIfNotExists)}"); diff --git a/sdk/tables/Azure.Data.Tables/src/TableServiceClient.cs b/sdk/tables/Azure.Data.Tables/src/TableServiceClient.cs index 77ff4f7e890c..cd177ad4e2a1 100644 --- a/sdk/tables/Azure.Data.Tables/src/TableServiceClient.cs +++ b/sdk/tables/Azure.Data.Tables/src/TableServiceClient.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.Linq.Expressions; using System.Net; @@ -685,7 +686,7 @@ public virtual async Task> CreateTableAsync(string tableName /// /// The name of the table to create. /// A controlling the request lifetime. - /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. + /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. public virtual Response CreateTableIfNotExists(string tableName, CancellationToken cancellationToken = default) { Argument.AssertNotNull(tableName, nameof(tableName)); @@ -724,7 +725,7 @@ public virtual Response CreateTableIfNotExists(string tableName, Canc /// /// The name of the table to create. /// A controlling the request lifetime. - /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. + /// A containing properties of the table. If the table already exists, then is 409. The can be accessed via the GetRawResponse() method. public virtual async Task> CreateTableIfNotExistsAsync(string tableName, CancellationToken cancellationToken = default) { Argument.AssertNotNull(tableName, nameof(tableName)); From 4f5e213c8202b7bca8dcd114ffc1beb621be990a Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 17:05:50 -0800 Subject: [PATCH 12/47] nit --- .../src/Azure.DigitalTwins.Core.csproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj index 461c6404cbd0..9e58ba5072a8 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Azure.DigitalTwins.Core.csproj @@ -19,6 +19,7 @@ + @@ -31,8 +32,5 @@ Shared\Azure.Core - - - From f56eb5a5659e4553721bb0c357f7a211894bc1d6 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 17:22:53 -0800 Subject: [PATCH 13/47] update --- ...or.cs => ClientModelPolicyCollectionAdapter.cs} | 14 ++++++++++++-- .../Azure.Core/src/Pipeline/HttpPipelinePolicy.cs | 4 ++-- .../src/Pipeline/Internal/ResponseBodyPolicy.cs | 2 +- sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) rename sdk/core/Azure.Core/src/Internal/{AzureCorePipelineProcessor.cs => ClientModelPolicyCollectionAdapter.cs} (66%) diff --git a/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs b/sdk/core/Azure.Core/src/Internal/ClientModelPolicyCollectionAdapter.cs similarity index 66% rename from sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs rename to sdk/core/Azure.Core/src/Internal/ClientModelPolicyCollectionAdapter.cs index 8b8b96ccb407..963a0b350734 100644 --- a/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs +++ b/sdk/core/Azure.Core/src/Internal/ClientModelPolicyCollectionAdapter.cs @@ -8,12 +8,22 @@ namespace Azure.Core.Pipeline { - internal struct AzureCorePipelineProcessor : IReadOnlyList + /// + /// Adapter from an Azure.Core pipeline to a System.ClientModel pipeline. + /// Azure.Core policies take + /// as the pipeline parameter of their + /// methods. System.ClientModel policies take . + /// + /// This type allows Azure.Core policies such as to + /// hold System.ClientModel policies internally and call their process methods + /// in a way that will continue passing control down the chain of policies. + /// + internal struct ClientModelPolicyCollectionAdapter : IReadOnlyList { private readonly ReadOnlyMemory _policies; private PolicyEnumerator? _enumerator; - public AzureCorePipelineProcessor(ReadOnlyMemory policies) + public ClientModelPolicyCollectionAdapter(ReadOnlyMemory policies) => _policies = policies; public ReadOnlyMemory Policies diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs index 0e5a37ed88e9..0b6a12f43ffe 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs @@ -64,7 +64,7 @@ public sealed override async ValueTask ProcessAsync(PipelineMessage message, IRe throw new InvalidOperationException($"Invalid type for message: '{message?.GetType()}'"); } - if (pipeline is not AzureCorePipelineProcessor processor) + if (pipeline is not ClientModelPolicyCollectionAdapter processor) { throw new InvalidOperationException($"Invalid type for pipeline: '{pipeline?.GetType()}'"); } @@ -89,7 +89,7 @@ public sealed override void Process(PipelineMessage message, IReadOnlyList pipeline, bool async) { - AzureCorePipelineProcessor processor = new(pipeline); + ClientModelPolicyCollectionAdapter processor = new(pipeline); // Get the network timeout for this particular invocation of the pipeline. // We either use the default that the policy was constructed with at diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs index b1873a04c6a5..53244193799c 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs @@ -53,7 +53,7 @@ public override void Process(HttpMessage message, ReadOnlyMemory pipeline, bool async) { - AzureCorePipelineProcessor processor = new(pipeline); + ClientModelPolicyCollectionAdapter processor = new(pipeline); try { From d9007f7d6df2f1c4136f45d96f8e8ba9e93d8452 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 17:28:00 -0800 Subject: [PATCH 14/47] update --- .../src/Pipeline/HttpClientTransport.Adapter.cs | 13 +++++++++++-- .../Azure.Core/src/Pipeline/HttpClientTransport.cs | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index 9028253d50e8..c9ccc49c0579 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -9,9 +9,18 @@ namespace Azure.Core.Pipeline { public partial class HttpClientTransport { - private class AzureCoreHttpPipelineTransport : HttpClientPipelineTransport + /// + /// Adapter from a System.ClientModel HttpClient-based transport to one + /// that implements the functionality required by Azure.Core. + /// + /// This type inherits from System.ClientModel's + /// and overrides the extensibility points for + /// and to add + /// features specific to Azure, such as . + /// + private class ClientModelHttpClientTransport : HttpClientPipelineTransport { - public AzureCoreHttpPipelineTransport(HttpClient client) : base(client) + public ClientModelHttpClientTransport(HttpClient client) : base(client) { } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs index 4bb679772725..f4d61707cd17 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs @@ -26,7 +26,7 @@ public partial class HttpClientTransport : HttpPipelineTransport, IDisposable // The transport's private HttpClient is internal because it is used by tests. internal HttpClient Client { get; } - private readonly AzureCoreHttpPipelineTransport _transport; + private readonly ClientModelHttpClientTransport _transport; /// /// Creates a new instance using default configuration. @@ -52,7 +52,7 @@ public HttpClientTransport(HttpClient client) { Client = client ?? throw new ArgumentNullException(nameof(client)); - _transport = new AzureCoreHttpPipelineTransport(client); + _transport = new ClientModelHttpClientTransport(client); } /// From f70793046d358156255a272cf7139e6a74b89dd3 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 17:31:28 -0800 Subject: [PATCH 15/47] update --- .../Pipeline/HttpClientTransport.Adapter.cs | 3 +- .../src/Pipeline/RetryPolicy.AzurePolicy.cs | 96 ------------------- .../Azure.Core/src/Pipeline/RetryPolicy.cs | 4 +- 3 files changed, 3 insertions(+), 100 deletions(-) delete mode 100644 sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index c9ccc49c0579..eb4e8bfad6bc 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -10,8 +10,7 @@ namespace Azure.Core.Pipeline public partial class HttpClientTransport { /// - /// Adapter from a System.ClientModel HttpClient-based transport to one - /// that implements the functionality required by Azure.Core. + /// Adds Azure.Core features to the System.ClientModel HttpClient-based transport. /// /// This type inherits from System.ClientModel's /// and overrides the extensibility points for diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs deleted file mode 100644 index c6f724a2f60f..000000000000 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.AzurePolicy.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.ClientModel.Primitives; -using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -using Azure.Core.Diagnostics; - -namespace Azure.Core.Pipeline; - -public partial class RetryPolicy -{ - internal class AzureCoreRetryPolicy : ClientRetryPolicy - { - private readonly RetryPolicy _pipelinePolicy; - private readonly DelayStrategy _delayStrategy; - - private long _beforeProcess; - private long _afterProcess; - private double _elapsedTime; - - public AzureCoreRetryPolicy(int maxRetries, DelayStrategy delay, RetryPolicy policy) - : base(maxRetries) - { - _delayStrategy = delay; - _pipelinePolicy = policy; - } - - protected override void OnSendingRequest(PipelineMessage message) - { - _beforeProcess = Stopwatch.GetTimestamp(); - - _pipelinePolicy.OnSendingRequest(HttpMessage.AssertHttpMessage(message)); - } - - protected override async ValueTask OnSendingRequestAsync(PipelineMessage message) - { - _beforeProcess = Stopwatch.GetTimestamp(); - - await _pipelinePolicy.OnSendingRequestAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); - } - - protected override void OnRequestSent(PipelineMessage message) - { - _pipelinePolicy.OnRequestSent(HttpMessage.AssertHttpMessage(message)); - - _afterProcess = Stopwatch.GetTimestamp(); - _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; - } - - protected override async ValueTask OnRequestSentAsync(PipelineMessage message) - { - await _pipelinePolicy.OnRequestSentAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); - - _afterProcess = Stopwatch.GetTimestamp(); - _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; - } - - protected override bool ShouldRetry(PipelineMessage message, Exception? exception) - => _pipelinePolicy.ShouldRetry(HttpMessage.AssertHttpMessage(message), exception); - - protected override async ValueTask ShouldRetryAsync(PipelineMessage message, Exception? exception) - => await _pipelinePolicy.ShouldRetryAsync(HttpMessage.AssertHttpMessage(message), exception).ConfigureAwait(false); - - protected override void OnTryComplete(PipelineMessage message) - { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); - httpMessage.RetryNumber++; - - AzureCoreEventSource.Singleton.RequestRetrying(httpMessage.Request.ClientRequestId, httpMessage.RetryNumber, _elapsedTime); - - // Reset stopwatch values - _afterProcess = default; - _beforeProcess = default; - _elapsedTime = default; - } - - protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) - { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); - - Debug.Assert(tryCount == httpMessage.RetryNumber); - - Response? response = httpMessage.HasResponse ? httpMessage.Response : default; - return _delayStrategy.GetNextDelay(response, tryCount + 1); - } - - protected override async Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) - => await _pipelinePolicy.WaitAsync(time, cancellationToken).ConfigureAwait(false); - - protected override void Wait(TimeSpan time, CancellationToken cancellationToken) - => _pipelinePolicy.Wait(time, cancellationToken); - } -} diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs index 53244193799c..081c391f055f 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs @@ -15,7 +15,7 @@ public partial class RetryPolicy : HttpPipelinePolicy { private readonly int _maxRetries; private readonly DelayStrategy _delayStrategy; - private readonly AzureCoreRetryPolicy _policy; + private readonly ClientModelRetryPolicy _policy; /// /// Initializes a new instance of the class. @@ -27,7 +27,7 @@ public RetryPolicy(int maxRetries = RetryOptions.DefaultMaxRetries, DelayStrateg _maxRetries = maxRetries; _delayStrategy = delayStrategy ?? DelayStrategy.CreateExponentialDelayStrategy(); - _policy = new AzureCoreRetryPolicy(maxRetries, _delayStrategy, this); + _policy = new ClientModelRetryPolicy(maxRetries, _delayStrategy, this); } /// From cbb794d943e884c472fbe2a7d1f180cabcda0128 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 17:31:43 -0800 Subject: [PATCH 16/47] missed file --- .../src/Pipeline/RetryPolicy.Adapter.cs | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs new file mode 100644 index 000000000000..c9b8e5da59d0 --- /dev/null +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel.Primitives; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core.Diagnostics; + +namespace Azure.Core.Pipeline; + +public partial class RetryPolicy +{ + /// + /// Adds Azure.Core features to the System.ClientModel retry policy. + /// + internal class ClientModelRetryPolicy : ClientRetryPolicy + { + private readonly RetryPolicy _pipelinePolicy; + private readonly DelayStrategy _delayStrategy; + + private long _beforeProcess; + private long _afterProcess; + private double _elapsedTime; + + public ClientModelRetryPolicy(int maxRetries, DelayStrategy delay, RetryPolicy policy) + : base(maxRetries) + { + _delayStrategy = delay; + _pipelinePolicy = policy; + } + + protected override void OnSendingRequest(PipelineMessage message) + { + _beforeProcess = Stopwatch.GetTimestamp(); + + _pipelinePolicy.OnSendingRequest(HttpMessage.AssertHttpMessage(message)); + } + + protected override async ValueTask OnSendingRequestAsync(PipelineMessage message) + { + _beforeProcess = Stopwatch.GetTimestamp(); + + await _pipelinePolicy.OnSendingRequestAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); + } + + protected override void OnRequestSent(PipelineMessage message) + { + _pipelinePolicy.OnRequestSent(HttpMessage.AssertHttpMessage(message)); + + _afterProcess = Stopwatch.GetTimestamp(); + _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; + } + + protected override async ValueTask OnRequestSentAsync(PipelineMessage message) + { + await _pipelinePolicy.OnRequestSentAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); + + _afterProcess = Stopwatch.GetTimestamp(); + _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; + } + + protected override bool ShouldRetry(PipelineMessage message, Exception? exception) + => _pipelinePolicy.ShouldRetry(HttpMessage.AssertHttpMessage(message), exception); + + protected override async ValueTask ShouldRetryAsync(PipelineMessage message, Exception? exception) + => await _pipelinePolicy.ShouldRetryAsync(HttpMessage.AssertHttpMessage(message), exception).ConfigureAwait(false); + + protected override void OnTryComplete(PipelineMessage message) + { + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + httpMessage.RetryNumber++; + + AzureCoreEventSource.Singleton.RequestRetrying(httpMessage.Request.ClientRequestId, httpMessage.RetryNumber, _elapsedTime); + + // Reset stopwatch values + _afterProcess = default; + _beforeProcess = default; + _elapsedTime = default; + } + + protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) + { + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + + Debug.Assert(tryCount == httpMessage.RetryNumber); + + Response? response = httpMessage.HasResponse ? httpMessage.Response : default; + return _delayStrategy.GetNextDelay(response, tryCount + 1); + } + + protected override async Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) + => await _pipelinePolicy.WaitAsync(time, cancellationToken).ConfigureAwait(false); + + protected override void Wait(TimeSpan time, CancellationToken cancellationToken) + => _pipelinePolicy.Wait(time, cancellationToken); + } +} From 897996eb560cfc63bf54a135835dcaa94d07b93d Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 5 Feb 2024 17:39:02 -0800 Subject: [PATCH 17/47] update --- sdk/core/Azure.Core/src/Request.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index 1da30c23ee7f..c0e3ceb361f3 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -122,7 +122,7 @@ protected override void SetContentCore(BinaryContent? content) /// /// protected override PipelineRequestHeaders GetHeadersCore() - => new AzureCoreMessageHeaders(Headers); + => new ClientModelRequestHeaders(Headers); #endregion @@ -180,16 +180,21 @@ protected internal virtual void SetHeader(string name, string value) protected internal abstract IEnumerable EnumerateHeaders(); /// - /// Backwards adapter to MessageHeaders to implement GetHeadersCore + /// This type adapts the Azure.Core RequestHeaders type to the System.ClientModel + /// PipelineRequestHeaders API. This enables to return + /// a PipelineRequestHeaders type without requiring that + /// inherit from . It calls through to the + /// implementation of Azure.Core RequestHeaders so that this functionality can + /// be maintained. /// - private sealed class AzureCoreMessageHeaders : PipelineRequestHeaders + private sealed class ClientModelRequestHeaders : PipelineRequestHeaders { /// /// Headers on the Azure.Core.Request type to adapt to. /// private readonly RequestHeaders _headers; - public AzureCoreMessageHeaders(RequestHeaders headers) + public ClientModelRequestHeaders(RequestHeaders headers) => _headers = headers; public override void Add(string name, string value) From 99b74b8f364189d5da45e0439e6dd710c97bedae Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 14 Feb 2024 13:51:50 -0800 Subject: [PATCH 18/47] client updates --- .../src/TablesRequestFailedDetailsParser.cs | 5 - .../src/TextAnalyticsFailedDetailsParser.cs | 115 ++++++++---------- 2 files changed, 52 insertions(+), 68 deletions(-) diff --git a/sdk/tables/Azure.Data.Tables/src/TablesRequestFailedDetailsParser.cs b/sdk/tables/Azure.Data.Tables/src/TablesRequestFailedDetailsParser.cs index 3642b101977f..16b643761d4e 100644 --- a/sdk/tables/Azure.Data.Tables/src/TablesRequestFailedDetailsParser.cs +++ b/sdk/tables/Azure.Data.Tables/src/TablesRequestFailedDetailsParser.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Text.Json; using Azure.Core; @@ -15,10 +14,6 @@ public override bool TryParse(Response response, out ResponseError error, out ID { error = null; data = null; - if (response.ContentStream == null || !(response.ContentStream is MemoryStream)) - { - return false; - } try { diff --git a/sdk/textanalytics/Azure.AI.TextAnalytics/src/TextAnalyticsFailedDetailsParser.cs b/sdk/textanalytics/Azure.AI.TextAnalytics/src/TextAnalyticsFailedDetailsParser.cs index bfef5d041667..88397cf7d03a 100644 --- a/sdk/textanalytics/Azure.AI.TextAnalytics/src/TextAnalyticsFailedDetailsParser.cs +++ b/sdk/textanalytics/Azure.AI.TextAnalytics/src/TextAnalyticsFailedDetailsParser.cs @@ -20,84 +20,73 @@ public override bool TryParse(Response response, out ResponseError? error, out I data = default; error = default; - if (response.ContentStream is { CanSeek: true }) + try { - long position = response.ContentStream.Position; + // Try to extract the standard Azure Error object from the response so that we can use it as the + // default value for the message, error code, etc. + using JsonDocument doc = JsonDocument.Parse(response.Content); + if (doc.RootElement.TryGetProperty("error", out JsonElement errorElement)) + { + TextAnalyticsError textAnalyticsError = Transforms.ConvertToError(Error.DeserializeError(errorElement)); + error = new ResponseError(textAnalyticsError.ErrorCode.ToString(), textAnalyticsError.Message); + return true; + } - try + // If the response does not straight up correspond to the standard Azure Error object that we are + // looking for, the Error object must actually be nested somewhere in there instead. For example, + // this can happen in the case of the convenience methods that receive a single input document as a + // parameter instead of a list of input documents. Here, rather than returning the typical + // successful response that includes a list of errors that the user needs to look through, we + // want to grab the first error in that list (which inevitably corresponds to a problem with the + // single input document), and use that error to throw a useful RequestFailedException. Now, + // depending on the circumstances, that standard Azure Error could be inside an InputError + // object, a DocumentError object, etc., so we need to look for it among a handful of well-known + // cases like those. + + if (doc.RootElement.TryGetProperty("errors", out JsonElement errorsElement)) { - // Try to extract the standard Azure Error object from the response so that we can use it as the - // default value for the message, error code, etc. + List errors = new(); - response.ContentStream.Position = 0; - using JsonDocument doc = JsonDocument.Parse(response.ContentStream); - if (doc.RootElement.TryGetProperty("error", out JsonElement errorElement)) + foreach (JsonElement item in errorsElement.EnumerateArray()) { - TextAnalyticsError textAnalyticsError = Transforms.ConvertToError(Error.DeserializeError(errorElement)); - error = new ResponseError(textAnalyticsError.ErrorCode.ToString(), textAnalyticsError.Message); - return true; + if (item.TryGetProperty("error", out errorElement)) + { + errors.Add(Error.DeserializeError(errorElement)); + } + else + { + errors.Add(Error.DeserializeError(item)); + } } - // If the response does not straight up correspond to the standard Azure Error object that we are - // looking for, the Error object must actually be nested somewhere in there instead. For example, - // this can happen in the case of the convenience methods that receive a single input document as a - // parameter instead of a list of input documents. Here, rather than returning the typical - // successful response that includes a list of errors that the user needs to look through, we - // want to grab the first error in that list (which inevitably corresponds to a problem with the - // single input document), and use that error to throw a useful RequestFailedException. Now, - // depending on the circumstances, that standard Azure Error could be inside an InputError - // object, a DocumentError object, etc., so we need to look for it among a handful of well-known - // cases like those. + GetResponseError(errors, out error, out data); + return true; + } - if (doc.RootElement.TryGetProperty("errors", out JsonElement errorsElement)) - { - List errors = new(); + if (doc.RootElement.TryGetProperty("results", out JsonElement results) && results.TryGetProperty("errors", out errorsElement)) + { + List errors = new(); - foreach (JsonElement item in errorsElement.EnumerateArray()) + foreach (JsonElement item in errorsElement.EnumerateArray()) + { + if (item.TryGetProperty("error", out errorElement)) { - if (item.TryGetProperty("error", out errorElement)) - { - errors.Add(Error.DeserializeError(errorElement)); - } - else - { - errors.Add(Error.DeserializeError(item)); - } + errors.Add(Error.DeserializeError(errorElement)); } - - GetResponseError(errors, out error, out data); - return true; - } - - if (doc.RootElement.TryGetProperty("results", out JsonElement results) && results.TryGetProperty("errors", out errorsElement)) - { - List errors = new(); - - foreach (JsonElement item in errorsElement.EnumerateArray()) + else { - if (item.TryGetProperty("error", out errorElement)) - { - errors.Add(Error.DeserializeError(errorElement)); - } - else - { - errors.Add(Error.DeserializeError(item)); - } + errors.Add(Error.DeserializeError(item)); } - - GetResponseError(errors, out error, out data); - return true; } + + GetResponseError(errors, out error, out data); + return true; } - catch (JsonException) - { - // Ignore any failures - unexpected content will be - // included verbatim in the detailed error message - } - finally - { - response.ContentStream.Position = position; - } + } + catch (JsonException) + { + // Ignore any failures - unexpected content will be + // included verbatim in the detailed error message } return false; From ebb3442f9a5c2b4ac7c8a217fe99ab990ba37182 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 14 Feb 2024 14:53:36 -0800 Subject: [PATCH 19/47] updates from recent PRs to feature branch --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 6 +- sdk/core/Azure.Core/api/Azure.Core.net472.cs | 6 +- sdk/core/Azure.Core/api/Azure.Core.net5.0.cs | 1176 ----------------- sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 6 +- .../api/Azure.Core.netcoreapp2.1.cs | 1173 ---------------- .../api/Azure.Core.netstandard2.0.cs | 6 +- sdk/core/Azure.Core/samples/Configuration.md | 1 + sdk/core/Azure.Core/src/ClientOptions.cs | 2 + sdk/core/Azure.Core/src/HttpMessage.cs | 26 +- .../Internal/AzureBaseBuffersExtensions.cs | 80 ++ ...apter.cs => AzureCorePipelineProcessor.cs} | 4 +- .../src/Pipeline/DisposableHttpPipeline.cs | 5 +- .../Pipeline/HttpClientTransport.Adapter.cs | 4 +- .../Pipeline/HttpClientTransport.Response.cs | 34 + .../src/Pipeline/HttpClientTransport.cs | 8 +- .../Azure.Core/src/Pipeline/HttpPipeline.cs | 30 +- .../src/Pipeline/HttpPipelineBuilder.cs | 16 +- .../src/Pipeline/HttpPipelinePolicy.cs | 4 +- .../Pipeline/HttpPipelineTransport.Adapter.cs | 49 + .../src/Pipeline/HttpPipelineTransport.cs | 24 +- .../src/Pipeline/HttpWebRequestTransport.cs | 2 + .../Internal/HttpPipelineTransportPolicy.cs | 4 +- .../src/Pipeline/Internal/LoggingPolicy.cs | 2 +- .../Pipeline/Internal/ResponseBodyPolicy.cs | 94 -- .../src/Pipeline/RetryPolicy.Adapter.cs | 4 +- .../Azure.Core/src/Pipeline/RetryPolicy.cs | 6 +- sdk/core/Azure.Core/src/Request.cs | 15 +- .../Azure.Core/src/RequestFailedException.cs | 55 +- sdk/core/Azure.Core/src/Response.cs | 120 +- sdk/core/Azure.Core/src/RetryOptions.cs | 2 +- .../src/Shared/CancellationHelper.cs | 22 +- .../tests/DisposableHttpPipelineTests.cs | 4 +- sdk/core/Azure.Core/tests/EventSourceTests.cs | 7 +- sdk/core/Azure.Core/tests/HttpMessageTests.cs | 48 + .../tests/HttpPipelineFunctionalTests.cs | 8 +- .../tests/ResponseBodyPolicyTests.cs | 402 ------ .../tests/ResponseBufferingTests.cs | 415 ++++++ .../Azure.Core/tests/RetriableStreamTests.cs | 31 +- .../tests/TransportFunctionalTests.cs | 9 +- .../src/Convenience/ClientResultOfT.cs | 2 +- .../ModelReaderWriterTests.cs | 13 +- .../Models/AvailabilitySetDataTests.cs | 4 +- .../Models/AvailabilitySetDataTestsWithVMs.cs | 8 +- .../ModelReaderWriterExtensions.cs | 4 +- .../ClientShared/ModelReaderWriterHelper.cs | 5 +- .../client/ClientShared/OptionalDictionary.cs | 6 +- .../tests/client/ClientShared/OptionalList.cs | 6 +- .../client/ClientShared/OptionalProperty.cs | 30 +- .../client/ClientShared/TypeFormatters.cs | 4 +- .../Models/DiscriminatorSet/BaseModel.cs | 20 +- .../Models/DiscriminatorSet/ModelX.cs | 29 +- .../Models/DiscriminatorSet/ModelY.cs | 23 +- .../DiscriminatorSet/UnknownBaseModel.cs | 4 +- .../ModelReaderWriter/Models/ModelAsStruct.cs | 2 +- .../Models/ModelWithPersistableOnly.cs | 44 +- .../ServiceModels/ApiProfile.Serialization.cs | 2 - .../ServiceModels/ApiProfile.cs | 2 - .../AvailabilitySetData.Serialization.cs | 2 - .../ServiceModels/AvailabilitySetData.cs | 2 - .../ServiceModels/ComputeSku.Serialization.cs | 2 - .../ServiceModels/ComputeSku.cs | 2 - .../ComputeStatusLevelType.Serialization.cs | 2 - .../ServiceModels/ComputeStatusLevelType.cs | 2 - .../ServiceModels/CreatedByType.cs | 2 - .../InstanceViewStatus.Serialization.cs | 2 - .../ServiceModels/InstanceViewStatus.cs | 2 - .../ProviderAuthorizationConsentState.cs | 2 - .../ProviderExtendedLocation.Serialization.cs | 2 - .../ServiceModels/ProviderExtendedLocation.cs | 2 - .../ProviderResourceType.Serialization.cs | 2 - .../ServiceModels/ProviderResourceType.cs | 2 - .../ServiceModels/ResourceData.cs | 13 +- .../ResourceProviderData.Serialization.cs | 2 - .../ServiceModels/ResourceProviderData.cs | 2 - .../ResourceTypeAlias.Serialization.cs | 2 - .../ServiceModels/ResourceTypeAlias.cs | 2 - .../ResourceTypeAliasPath.Serialization.cs | 2 - .../ServiceModels/ResourceTypeAliasPath.cs | 2 - .../ResourceTypeAliasPathAttributes.cs | 2 - ...urceTypeAliasPathMetadata.Serialization.cs | 2 - .../ResourceTypeAliasPathMetadata.cs | 2 - .../ResourceTypeAliasPathTokenType.cs | 2 - .../ResourceTypeAliasPattern.Serialization.cs | 2 - .../ServiceModels/ResourceTypeAliasPattern.cs | 2 - ...ourceTypeAliasPatternType.Serialization.cs | 2 - .../ResourceTypeAliasPatternType.cs | 2 - .../ResourceTypeAliasType.Serialization.cs | 2 - .../ServiceModels/ResourceTypeAliasType.cs | 2 - .../ServiceModels/SystemData.Serialization.cs | 33 +- .../ServiceModels/SystemData.cs | 2 - .../ServiceModels/TrackedResourceData.cs | 27 +- .../WritableSubResource.Serialization.cs | 8 +- .../ServiceModels/WritableSubResource.cs | 4 +- .../ZoneMapping.Serialization.cs | 2 - .../ServiceModels/ZoneMapping.cs | 2 - .../System.ClientModel.Tests.Client.csproj | 1 + .../tests/client/TestData.cs | 3 +- .../JsonModelConverterTests.cs | 9 +- 98 files changed, 1140 insertions(+), 3142 deletions(-) delete mode 100644 sdk/core/Azure.Core/api/Azure.Core.net5.0.cs delete mode 100644 sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs rename sdk/core/Azure.Core/src/Internal/{ClientModelPolicyCollectionAdapter.cs => AzureCorePipelineProcessor.cs} (92%) create mode 100644 sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs delete mode 100644 sdk/core/Azure.Core/src/Pipeline/Internal/ResponseBodyPolicy.cs delete mode 100644 sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs create mode 100644 sdk/core/Azure.Core/tests/ResponseBufferingTests.cs diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index a850bca34665..0d825ec9eed9 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -232,6 +232,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } @@ -239,13 +240,15 @@ public abstract partial class Response : System.ClientModel.Primitives.PipelineR { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual new System.BinaryData Content { get { throw null; } } + public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + public override System.BinaryData ReadContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask ReadContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } @@ -495,6 +498,7 @@ public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier res public new Azure.Core.Request Request { get { throw null; } } public new Azure.Response Response { get { throw null; } set { } } public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index a850bca34665..0d825ec9eed9 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -232,6 +232,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } @@ -239,13 +240,15 @@ public abstract partial class Response : System.ClientModel.Primitives.PipelineR { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual new System.BinaryData Content { get { throw null; } } + public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + public override System.BinaryData ReadContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask ReadContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } @@ -495,6 +498,7 @@ public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier res public new Azure.Core.Request Request { get { throw null; } } public new Azure.Response Response { get { throw null; } set { } } public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } diff --git a/sdk/core/Azure.Core/api/Azure.Core.net5.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net5.0.cs deleted file mode 100644 index 6d7fede912ff..000000000000 --- a/sdk/core/Azure.Core/api/Azure.Core.net5.0.cs +++ /dev/null @@ -1,1176 +0,0 @@ -namespace Azure -{ - public abstract partial class AsyncPageable : System.Collections.Generic.IAsyncEnumerable where T : notnull - { - protected AsyncPageable() { } - protected AsyncPageable(System.Threading.CancellationToken cancellationToken) { } - protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public abstract System.Collections.Generic.IAsyncEnumerable> AsPages(string? continuationToken = null, int? pageSizeHint = default(int?)); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - public static Azure.AsyncPageable FromPages(System.Collections.Generic.IEnumerable> pages) { throw null; } - public virtual System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - public static partial class AzureCoreExtensions - { - public static dynamic ToDynamicFromJson(this System.BinaryData utf8Json) { throw null; } - public static dynamic ToDynamicFromJson(this System.BinaryData utf8Json, Azure.Core.Serialization.JsonPropertyNames propertyNameFormat, string dateTimeFormat = "o") { throw null; } - public static System.Threading.Tasks.ValueTask ToObjectAsync(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } - public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public partial class AzureKeyCredential - { - public AzureKeyCredential(string key) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public string Key { get { throw null; } } - public void Update(string key) { } - } - public partial class AzureNamedKeyCredential - { - public AzureNamedKeyCredential(string name, string key) { } - public string Name { get { throw null; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public void Deconstruct(out string name, out string key) { throw null; } - public void Update(string name, string key) { } - } - public partial class AzureSasCredential - { - public AzureSasCredential(string signature) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public string Signature { get { throw null; } } - public void Update(string signature) { } - } - [System.FlagsAttribute] - public enum ErrorOptions - { - Default = 0, - NoThrow = 1, - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ETag : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public static readonly Azure.ETag All; - public ETag(string etag) { throw null; } - public bool Equals(Azure.ETag other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public bool Equals(string? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.ETag left, Azure.ETag right) { throw null; } - public static bool operator !=(Azure.ETag left, Azure.ETag right) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string ToString() { throw null; } - public string ToString(string format) { throw null; } - } - public partial class HttpAuthorization - { - public HttpAuthorization(string scheme, string parameter) { } - public string Parameter { get { throw null; } } - public string Scheme { get { throw null; } } - public override string ToString() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct HttpRange : System.IEquatable - { - private readonly int _dummyPrimitive; - public HttpRange(long offset = (long)0, long? length = default(long?)) { throw null; } - public long? Length { get { throw null; } } - public long Offset { get { throw null; } } - public bool Equals(Azure.HttpRange other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.HttpRange left, Azure.HttpRange right) { throw null; } - public static bool operator !=(Azure.HttpRange left, Azure.HttpRange right) { throw null; } - public override string ToString() { throw null; } - } - public partial class JsonPatchDocument - { - public JsonPatchDocument() { } - public JsonPatchDocument(Azure.Core.Serialization.ObjectSerializer serializer) { } - public JsonPatchDocument(System.ReadOnlyMemory rawDocument) { } - public JsonPatchDocument(System.ReadOnlyMemory rawDocument, Azure.Core.Serialization.ObjectSerializer serializer) { } - public void AppendAddRaw(string path, string rawJsonValue) { } - public void AppendAdd(string path, T value) { } - public void AppendCopy(string from, string path) { } - public void AppendMove(string from, string path) { } - public void AppendRemove(string path) { } - public void AppendReplaceRaw(string path, string rawJsonValue) { } - public void AppendReplace(string path, T value) { } - public void AppendTestRaw(string path, string rawJsonValue) { } - public void AppendTest(string path, T value) { } - public System.ReadOnlyMemory ToBytes() { throw null; } - public override string ToString() { throw null; } - } - public partial class MatchConditions - { - public MatchConditions() { } - public Azure.ETag? IfMatch { get { throw null; } set { } } - public Azure.ETag? IfNoneMatch { get { throw null; } set { } } - } - public abstract partial class NullableResponse - { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); - public override string ToString() { throw null; } - } - public abstract partial class Operation - { - protected Operation() { } - public abstract bool HasCompleted { get; } - public abstract string Id { get; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - public abstract Azure.Response UpdateStatus(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public abstract System.Threading.Tasks.ValueTask UpdateStatusAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public virtual Azure.Response WaitForCompletionResponse(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual Azure.Response WaitForCompletionResponse(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual Azure.Response WaitForCompletionResponse(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public abstract partial class Operation : Azure.Operation where T : notnull - { - protected Operation() { } - public abstract bool HasValue { get; } - public abstract T Value { get; } - public virtual Azure.Response WaitForCompletion(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken) { throw null; } - public virtual Azure.Response WaitForCompletion(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual Azure.Response WaitForCompletion(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken) { throw null; } - public virtual System.Threading.Tasks.ValueTask> WaitForCompletionAsync(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken) { throw null; } - public virtual System.Threading.Tasks.ValueTask> WaitForCompletionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask> WaitForCompletionAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public abstract partial class PageableOperation : Azure.Operation> where T : notnull - { - protected PageableOperation() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override Azure.AsyncPageable Value { get { throw null; } } - public abstract Azure.Pageable GetValues(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public abstract Azure.AsyncPageable GetValuesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - } - public abstract partial class Pageable : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable where T : notnull - { - protected Pageable() { } - protected Pageable(System.Threading.CancellationToken cancellationToken) { } - protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public abstract System.Collections.Generic.IEnumerable> AsPages(string? continuationToken = null, int? pageSizeHint = default(int?)); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - public static Azure.Pageable FromPages(System.Collections.Generic.IEnumerable> pages) { throw null; } - public virtual System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - public abstract partial class Page - { - protected Page() { } - public abstract string? ContinuationToken { get; } - public abstract System.Collections.Generic.IReadOnlyList Values { get; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - public static Azure.Page FromValues(System.Collections.Generic.IReadOnlyList values, string? continuationToken, Azure.Response response) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - public partial class RequestConditions : Azure.MatchConditions - { - public RequestConditions() { } - public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } - public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } - } - public partial class RequestContext - { - public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } - public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } - public void AddClassifier(int statusCode, bool isError) { } - public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } - public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } - } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable - { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } - public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } - public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } - } - public abstract partial class Response : System.IDisposable - { - protected Response() { } - public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } - protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); - protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); - public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } - public override string ToString() { throw null; } - protected internal abstract bool TryGetHeader(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value); - protected internal abstract bool TryGetHeaderValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values); - } - public sealed partial class ResponseError - { - public ResponseError(string? code, string? message) { } - public string? Code { get { throw null; } } - public string? Message { get { throw null; } } - public override string ToString() { throw null; } - } - public abstract partial class Response : Azure.NullableResponse - { - protected Response() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool HasValue { get { throw null; } } - public override T Value { get { throw null; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static implicit operator T (Azure.Response response) { throw null; } - } - public partial class SyncAsyncEventArgs : System.EventArgs - { - public SyncAsyncEventArgs(bool isRunningSynchronously, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } - public bool IsRunningSynchronously { get { throw null; } } - } - public enum WaitUntil - { - Completed = 0, - Started = 1, - } -} -namespace Azure.Core -{ - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public partial struct AccessToken - { - private object _dummy; - private int _dummyPrimitive; - public AccessToken(string accessToken, System.DateTimeOffset expiresOn) { throw null; } - public System.DateTimeOffset ExpiresOn { get { throw null; } } - public string Token { get { throw null; } } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct AzureLocation : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public AzureLocation(string location) { throw null; } - public AzureLocation(string name, string displayName) { throw null; } - public static Azure.Core.AzureLocation AustraliaCentral { get { throw null; } } - public static Azure.Core.AzureLocation AustraliaCentral2 { get { throw null; } } - public static Azure.Core.AzureLocation AustraliaEast { get { throw null; } } - public static Azure.Core.AzureLocation AustraliaSoutheast { get { throw null; } } - public static Azure.Core.AzureLocation BrazilSouth { get { throw null; } } - public static Azure.Core.AzureLocation BrazilSoutheast { get { throw null; } } - public static Azure.Core.AzureLocation CanadaCentral { get { throw null; } } - public static Azure.Core.AzureLocation CanadaEast { get { throw null; } } - public static Azure.Core.AzureLocation CentralIndia { get { throw null; } } - public static Azure.Core.AzureLocation CentralUS { get { throw null; } } - public static Azure.Core.AzureLocation ChinaEast { get { throw null; } } - public static Azure.Core.AzureLocation ChinaEast2 { get { throw null; } } - public static Azure.Core.AzureLocation ChinaNorth { get { throw null; } } - public static Azure.Core.AzureLocation ChinaNorth2 { get { throw null; } } - public string? DisplayName { get { throw null; } } - public static Azure.Core.AzureLocation EastAsia { get { throw null; } } - public static Azure.Core.AzureLocation EastUS { get { throw null; } } - public static Azure.Core.AzureLocation EastUS2 { get { throw null; } } - public static Azure.Core.AzureLocation FranceCentral { get { throw null; } } - public static Azure.Core.AzureLocation FranceSouth { get { throw null; } } - public static Azure.Core.AzureLocation GermanyCentral { get { throw null; } } - public static Azure.Core.AzureLocation GermanyNorth { get { throw null; } } - public static Azure.Core.AzureLocation GermanyNorthEast { get { throw null; } } - public static Azure.Core.AzureLocation GermanyWestCentral { get { throw null; } } - public static Azure.Core.AzureLocation JapanEast { get { throw null; } } - public static Azure.Core.AzureLocation JapanWest { get { throw null; } } - public static Azure.Core.AzureLocation KoreaCentral { get { throw null; } } - public static Azure.Core.AzureLocation KoreaSouth { get { throw null; } } - public string Name { get { throw null; } } - public static Azure.Core.AzureLocation NorthCentralUS { get { throw null; } } - public static Azure.Core.AzureLocation NorthEurope { get { throw null; } } - public static Azure.Core.AzureLocation NorwayEast { get { throw null; } } - public static Azure.Core.AzureLocation NorwayWest { get { throw null; } } - public static Azure.Core.AzureLocation QatarCentral { get { throw null; } } - public static Azure.Core.AzureLocation SouthAfricaNorth { get { throw null; } } - public static Azure.Core.AzureLocation SouthAfricaWest { get { throw null; } } - public static Azure.Core.AzureLocation SouthCentralUS { get { throw null; } } - public static Azure.Core.AzureLocation SoutheastAsia { get { throw null; } } - public static Azure.Core.AzureLocation SouthIndia { get { throw null; } } - public static Azure.Core.AzureLocation SwedenCentral { get { throw null; } } - public static Azure.Core.AzureLocation SwitzerlandNorth { get { throw null; } } - public static Azure.Core.AzureLocation SwitzerlandWest { get { throw null; } } - public static Azure.Core.AzureLocation UAECentral { get { throw null; } } - public static Azure.Core.AzureLocation UAENorth { get { throw null; } } - public static Azure.Core.AzureLocation UKSouth { get { throw null; } } - public static Azure.Core.AzureLocation UKWest { get { throw null; } } - public static Azure.Core.AzureLocation USDoDCentral { get { throw null; } } - public static Azure.Core.AzureLocation USDoDEast { get { throw null; } } - public static Azure.Core.AzureLocation USGovArizona { get { throw null; } } - public static Azure.Core.AzureLocation USGovIowa { get { throw null; } } - public static Azure.Core.AzureLocation USGovTexas { get { throw null; } } - public static Azure.Core.AzureLocation USGovVirginia { get { throw null; } } - public static Azure.Core.AzureLocation WestCentralUS { get { throw null; } } - public static Azure.Core.AzureLocation WestEurope { get { throw null; } } - public static Azure.Core.AzureLocation WestIndia { get { throw null; } } - public static Azure.Core.AzureLocation WestUS { get { throw null; } } - public static Azure.Core.AzureLocation WestUS2 { get { throw null; } } - public static Azure.Core.AzureLocation WestUS3 { get { throw null; } } - public bool Equals(Azure.Core.AzureLocation other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } - public static implicit operator string (Azure.Core.AzureLocation location) { throw null; } - public static implicit operator Azure.Core.AzureLocation (string location) { throw null; } - public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } - public override string ToString() { throw null; } - } - public abstract partial class ClientOptions - { - protected ClientOptions() { } - protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } - public static Azure.Core.ClientOptions Default { get { throw null; } } - public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } - public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } - public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ContentType : System.IEquatable, System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public ContentType(string contentType) { throw null; } - public static Azure.Core.ContentType ApplicationJson { get { throw null; } } - public static Azure.Core.ContentType ApplicationOctetStream { get { throw null; } } - public static Azure.Core.ContentType TextPlain { get { throw null; } } - public bool Equals(Azure.Core.ContentType other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public bool Equals(string? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.ContentType left, Azure.Core.ContentType right) { throw null; } - public static implicit operator Azure.Core.ContentType (string contentType) { throw null; } - public static bool operator !=(Azure.Core.ContentType left, Azure.Core.ContentType right) { throw null; } - public override string ToString() { throw null; } - } - public abstract partial class DelayStrategy - { - protected DelayStrategy(System.TimeSpan? maxDelay = default(System.TimeSpan?), double jitterFactor = 0.2) { } - public static Azure.Core.DelayStrategy CreateExponentialDelayStrategy(System.TimeSpan? initialDelay = default(System.TimeSpan?), System.TimeSpan? maxDelay = default(System.TimeSpan?)) { throw null; } - public static Azure.Core.DelayStrategy CreateFixedDelayStrategy(System.TimeSpan? delay = default(System.TimeSpan?)) { throw null; } - public System.TimeSpan GetNextDelay(Azure.Response? response, int retryNumber) { throw null; } - protected abstract System.TimeSpan GetNextDelayCore(Azure.Response? response, int retryNumber); - protected static System.TimeSpan Max(System.TimeSpan val1, System.TimeSpan val2) { throw null; } - protected static System.TimeSpan Min(System.TimeSpan val1, System.TimeSpan val2) { throw null; } - } - public static partial class DelegatedTokenCredential - { - public static Azure.Core.TokenCredential Create(System.Func getToken) { throw null; } - public static Azure.Core.TokenCredential Create(System.Func getToken, System.Func> getTokenAsync) { throw null; } - } - public partial class DiagnosticsOptions - { - protected internal DiagnosticsOptions() { } - public string? ApplicationId { get { throw null; } set { } } - public static string? DefaultApplicationId { get { throw null; } set { } } - public bool IsDistributedTracingEnabled { get { throw null; } set { } } - public bool IsLoggingContentEnabled { get { throw null; } set { } } - public bool IsLoggingEnabled { get { throw null; } set { } } - public bool IsTelemetryEnabled { get { throw null; } set { } } - public int LoggedContentSizeLimit { get { throw null; } set { } } - public System.Collections.Generic.IList LoggedHeaderNames { get { throw null; } } - public System.Collections.Generic.IList LoggedQueryParameters { get { throw null; } } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct HttpHeader : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public HttpHeader(string name, string value) { throw null; } - public string Name { get { throw null; } } - public string Value { get { throw null; } } - public bool Equals(Azure.Core.HttpHeader other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public override string ToString() { throw null; } - public static partial class Common - { - public static readonly Azure.Core.HttpHeader FormUrlEncodedContentType; - public static readonly Azure.Core.HttpHeader JsonAccept; - public static readonly Azure.Core.HttpHeader JsonContentType; - public static readonly Azure.Core.HttpHeader OctetStreamContentType; - } - public static partial class Names - { - public static string Accept { get { throw null; } } - public static string Authorization { get { throw null; } } - public static string ContentDisposition { get { throw null; } } - public static string ContentLength { get { throw null; } } - public static string ContentType { get { throw null; } } - public static string Date { get { throw null; } } - public static string ETag { get { throw null; } } - public static string Host { get { throw null; } } - public static string IfMatch { get { throw null; } } - public static string IfModifiedSince { get { throw null; } } - public static string IfNoneMatch { get { throw null; } } - public static string IfUnmodifiedSince { get { throw null; } } - public static string Prefer { get { throw null; } } - public static string Range { get { throw null; } } - public static string Referer { get { throw null; } } - public static string UserAgent { get { throw null; } } - public static string WwwAuthenticate { get { throw null; } } - public static string XMsDate { get { throw null; } } - public static string XMsRange { get { throw null; } } - public static string XMsRequestId { get { throw null; } } - } - } - public sealed partial class HttpMessage : System.IDisposable - { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } - public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } - public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } - public System.IO.Stream? ExtractResponseContent() { throw null; } - public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } - public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } - } - public enum HttpPipelinePosition - { - PerCall = 0, - PerRetry = 1, - BeforeTransport = 2, - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct MessageProcessingContext - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public int RetryNumber { get { throw null; } set { } } - public System.DateTimeOffset StartTime { get { throw null; } } - } - public static partial class MultipartResponse - { - public static Azure.Response[] Parse(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } - public static System.Threading.Tasks.Task ParseAsync(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } - } - public abstract partial class Request : System.IDisposable - { - protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } - protected internal abstract void AddHeader(string name, string value); - protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); - protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); - protected internal abstract bool RemoveHeader(string name); - protected internal virtual void SetHeader(string name, string value) { } - protected internal abstract bool TryGetHeader(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value); - protected internal abstract bool TryGetHeaderValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values); - } - public abstract partial class RequestContent : System.IDisposable - { - protected RequestContent() { } - public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } - public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } - public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } - public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } - public static Azure.Core.RequestContent Create(System.IO.Stream stream) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method uses reflection-based serialization which is incompatible with trimming. Try using one of the 'Create' overloads that doesn't wrap a serialized version of an object.")] - public static Azure.Core.RequestContent Create(object serializable) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method uses reflection-based serialization which is incompatible with trimming. Try using one of the 'Create' overloads that doesn't wrap a serialized version of an object.")] - public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.JsonPropertyNames propertyNameFormat, string dateTimeFormat = "o") { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method uses reflection-based serialization which is incompatible with trimming. Try using one of the 'Create' overloads that doesn't wrap a serialized version of an object.")] - public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } - public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } - public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); - public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } - public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } - public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - } - public abstract partial class RequestFailedDetailsParser - { - protected RequestFailedDetailsParser() { } - public abstract bool TryParse(Azure.Response response, out Azure.ResponseError? error, out System.Collections.Generic.IDictionary? data); - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct RequestHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public void Add(Azure.Core.HttpHeader header) { } - public void Add(string name, string value) { } - public bool Contains(string name) { throw null; } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - public bool Remove(string name) { throw null; } - public void SetValue(string name, string value) { } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - public bool TryGetValue(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value) { throw null; } - public bool TryGetValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values) { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct RequestMethod : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public RequestMethod(string method) { throw null; } - public static Azure.Core.RequestMethod Delete { get { throw null; } } - public static Azure.Core.RequestMethod Get { get { throw null; } } - public static Azure.Core.RequestMethod Head { get { throw null; } } - public string Method { get { throw null; } } - public static Azure.Core.RequestMethod Options { get { throw null; } } - public static Azure.Core.RequestMethod Patch { get { throw null; } } - public static Azure.Core.RequestMethod Post { get { throw null; } } - public static Azure.Core.RequestMethod Put { get { throw null; } } - public static Azure.Core.RequestMethod Trace { get { throw null; } } - public bool Equals(Azure.Core.RequestMethod other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.RequestMethod left, Azure.Core.RequestMethod right) { throw null; } - public static bool operator !=(Azure.Core.RequestMethod left, Azure.Core.RequestMethod right) { throw null; } - public static Azure.Core.RequestMethod Parse(string method) { throw null; } - public override string ToString() { throw null; } - } - public partial class RequestUriBuilder - { - public RequestUriBuilder() { } - protected bool HasPath { get { throw null; } } - protected bool HasQuery { get { throw null; } } - public string? Host { get { throw null; } set { } } - public string Path { get { throw null; } set { } } - public string PathAndQuery { get { throw null; } } - public int Port { get { throw null; } set { } } - public string Query { get { throw null; } set { } } - public string? Scheme { get { throw null; } set { } } - public void AppendPath(System.ReadOnlySpan value, bool escape) { } - public void AppendPath(string value) { } - public void AppendPath(string value, bool escape) { } - public void AppendQuery(System.ReadOnlySpan name, System.ReadOnlySpan value, bool escapeValue) { } - public void AppendQuery(string name, string value) { } - public void AppendQuery(string name, string value, bool escapeValue) { } - public void Reset(System.Uri value) { } - public override string ToString() { throw null; } - public System.Uri ToUri() { throw null; } - } - public sealed partial class ResourceIdentifier : System.IComparable, System.IEquatable - { - public static readonly Azure.Core.ResourceIdentifier Root; - public ResourceIdentifier(string resourceId) { } - public Azure.Core.AzureLocation? Location { get { throw null; } } - public string Name { get { throw null; } } - public Azure.Core.ResourceIdentifier? Parent { get { throw null; } } - public string? Provider { get { throw null; } } - public string? ResourceGroupName { get { throw null; } } - public Azure.Core.ResourceType ResourceType { get { throw null; } } - public string? SubscriptionId { get { throw null; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public Azure.Core.ResourceIdentifier AppendChildResource(string childResourceType, string childResourceName) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public Azure.Core.ResourceIdentifier AppendProviderResource(string providerNamespace, string resourceType, string resourceName) { throw null; } - public int CompareTo(Azure.Core.ResourceIdentifier? other) { throw null; } - public bool Equals(Azure.Core.ResourceIdentifier? other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator >(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator >=(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static implicit operator string (Azure.Core.ResourceIdentifier id) { throw null; } - public static bool operator !=(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator <(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator <=(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static Azure.Core.ResourceIdentifier Parse(string input) { throw null; } - public override string ToString() { throw null; } - public static bool TryParse(string? input, out Azure.Core.ResourceIdentifier? result) { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ResourceType : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public ResourceType(string resourceType) { throw null; } - public string Namespace { get { throw null; } } - public string Type { get { throw null; } } - public bool Equals(Azure.Core.ResourceType other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public string GetLastType() { throw null; } - public static bool operator ==(Azure.Core.ResourceType left, Azure.Core.ResourceType right) { throw null; } - public static implicit operator string (Azure.Core.ResourceType resourceType) { throw null; } - public static implicit operator Azure.Core.ResourceType (string resourceType) { throw null; } - public static bool operator !=(Azure.Core.ResourceType left, Azure.Core.ResourceType right) { throw null; } - public override string ToString() { throw null; } - } - public abstract partial class ResponseClassificationHandler - { - protected ResponseClassificationHandler() { } - public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); - } - public partial class ResponseClassifier - { - public ResponseClassifier() { } - public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } - public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } - public virtual bool IsRetriableException(System.Exception exception) { throw null; } - public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public int? ContentLength { get { throw null; } } - public long? ContentLengthLong { get { throw null; } } - public string? ContentType { get { throw null; } } - public System.DateTimeOffset? Date { get { throw null; } } - public Azure.ETag? ETag { get { throw null; } } - public string? RequestId { get { throw null; } } - public bool Contains(string name) { throw null; } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - public bool TryGetValue(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value) { throw null; } - public bool TryGetValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values) { throw null; } - } - public enum RetryMode - { - Fixed = 0, - Exponential = 1, - } - public partial class RetryOptions - { - internal RetryOptions() { } - public System.TimeSpan Delay { get { throw null; } set { } } - public System.TimeSpan MaxDelay { get { throw null; } set { } } - public int MaxRetries { get { throw null; } set { } } - public Azure.Core.RetryMode Mode { get { throw null; } set { } } - public System.TimeSpan NetworkTimeout { get { throw null; } set { } } - } - public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier - { - public StatusCodeClassifier(System.ReadOnlySpan successStatusCodes) { } - public override bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } - } - public delegate System.Threading.Tasks.Task SyncAsyncEventHandler(T e) where T : Azure.SyncAsyncEventArgs; - public partial class TelemetryDetails - { - public TelemetryDetails(System.Reflection.Assembly assembly, string? applicationId = null) { } - public string? ApplicationId { get { throw null; } } - public System.Reflection.Assembly Assembly { get { throw null; } } - public void Apply(Azure.Core.HttpMessage message) { } - public override string ToString() { throw null; } - } - public abstract partial class TokenCredential - { - protected TokenCredential() { } - public abstract Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - public abstract System.Threading.Tasks.ValueTask GetTokenAsync(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct TokenRequestContext - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public TokenRequestContext(string[] scopes, string? parentRequestId) { throw null; } - public TokenRequestContext(string[] scopes, string? parentRequestId, string? claims) { throw null; } - public TokenRequestContext(string[] scopes, string? parentRequestId, string? claims, string? tenantId) { throw null; } - public TokenRequestContext(string[] scopes, string? parentRequestId = null, string? claims = null, string? tenantId = null, bool isCaeEnabled = false) { throw null; } - public string? Claims { get { throw null; } } - public bool IsCaeEnabled { get { throw null; } } - public string? ParentRequestId { get { throw null; } } - public string[] Scopes { get { throw null; } } - public string? TenantId { get { throw null; } } - } -} -namespace Azure.Core.Cryptography -{ - public partial interface IKeyEncryptionKey - { - string KeyId { get; } - byte[] UnwrapKey(string algorithm, System.ReadOnlyMemory encryptedKey, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - System.Threading.Tasks.Task UnwrapKeyAsync(string algorithm, System.ReadOnlyMemory encryptedKey, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - byte[] WrapKey(string algorithm, System.ReadOnlyMemory key, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - System.Threading.Tasks.Task WrapKeyAsync(string algorithm, System.ReadOnlyMemory key, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - } - public partial interface IKeyEncryptionKeyResolver - { - Azure.Core.Cryptography.IKeyEncryptionKey Resolve(string keyId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - System.Threading.Tasks.Task ResolveAsync(string keyId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - } -} -namespace Azure.Core.Diagnostics -{ - public partial class AzureEventSourceListener : System.Diagnostics.Tracing.EventListener - { - public const string TraitName = "AzureEventSource"; - public const string TraitValue = "true"; - public AzureEventSourceListener(System.Action log, System.Diagnostics.Tracing.EventLevel level) { } - public static Azure.Core.Diagnostics.AzureEventSourceListener CreateConsoleLogger(System.Diagnostics.Tracing.EventLevel level = System.Diagnostics.Tracing.EventLevel.Informational) { throw null; } - public static Azure.Core.Diagnostics.AzureEventSourceListener CreateTraceLogger(System.Diagnostics.Tracing.EventLevel level = System.Diagnostics.Tracing.EventLevel.Informational) { throw null; } - protected sealed override void OnEventSourceCreated(System.Diagnostics.Tracing.EventSource eventSource) { } - protected sealed override void OnEventWritten(System.Diagnostics.Tracing.EventWrittenEventArgs eventData) { } - } -} -namespace Azure.Core.Extensions -{ - public partial interface IAzureClientBuilder where TOptions : class - { - } - public partial interface IAzureClientFactoryBuilder - { - Azure.Core.Extensions.IAzureClientBuilder RegisterClientFactory(System.Func clientFactory) where TOptions : class; - } - public partial interface IAzureClientFactoryBuilderWithConfiguration : Azure.Core.Extensions.IAzureClientFactoryBuilder - { - Azure.Core.Extensions.IAzureClientBuilder RegisterClientFactory(TConfiguration configuration) where TOptions : class; - } - public partial interface IAzureClientFactoryBuilderWithCredential - { - Azure.Core.Extensions.IAzureClientBuilder RegisterClientFactory(System.Func clientFactory, bool requiresCredential = true) where TOptions : class; - } -} -namespace Azure.Core.GeoJson -{ - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct GeoArray : System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public int Count { get { throw null; } } - public T this[int index] { get { throw null; } } - public Azure.Core.GeoJson.GeoArray.Enumerator GetEnumerator() { throw null; } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public partial struct Enumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable - { - private object _dummy; - private int _dummyPrimitive; - public T Current { get { throw null; } } - object System.Collections.IEnumerator.Current { get { throw null; } } - public void Dispose() { } - public bool MoveNext() { throw null; } - public void Reset() { } - } - } - public sealed partial class GeoBoundingBox : System.IEquatable - { - public GeoBoundingBox(double west, double south, double east, double north) { } - public GeoBoundingBox(double west, double south, double east, double north, double? minAltitude, double? maxAltitude) { } - public double East { get { throw null; } } - public double this[int index] { get { throw null; } } - public double? MaxAltitude { get { throw null; } } - public double? MinAltitude { get { throw null; } } - public double North { get { throw null; } } - public double South { get { throw null; } } - public double West { get { throw null; } } - public bool Equals(Azure.Core.GeoJson.GeoBoundingBox? other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public override string ToString() { throw null; } - } - public sealed partial class GeoCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoCollection(System.Collections.Generic.IEnumerable geometries) { } - public GeoCollection(System.Collections.Generic.IEnumerable geometries, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoObject this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public sealed partial class GeoLinearRing - { - public GeoLinearRing(System.Collections.Generic.IEnumerable coordinates) { } - public Azure.Core.GeoJson.GeoArray Coordinates { get { throw null; } } - } - public sealed partial class GeoLineString : Azure.Core.GeoJson.GeoObject - { - public GeoLineString(System.Collections.Generic.IEnumerable coordinates) { } - public GeoLineString(System.Collections.Generic.IEnumerable coordinates, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray Coordinates { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - } - public sealed partial class GeoLineStringCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoLineStringCollection(System.Collections.Generic.IEnumerable lines) { } - public GeoLineStringCollection(System.Collections.Generic.IEnumerable lines, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray> Coordinates { get { throw null; } } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoLineString this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public abstract partial class GeoObject - { - internal GeoObject() { } - public Azure.Core.GeoJson.GeoBoundingBox? BoundingBox { get { throw null; } } - public abstract Azure.Core.GeoJson.GeoObjectType Type { get; } - public static Azure.Core.GeoJson.GeoObject Parse(string json) { throw null; } - public override string ToString() { throw null; } - public bool TryGetCustomProperty(string name, out object? value) { throw null; } - } - public enum GeoObjectType - { - Point = 0, - MultiPoint = 1, - Polygon = 2, - MultiPolygon = 3, - LineString = 4, - MultiLineString = 5, - GeometryCollection = 6, - } - public sealed partial class GeoPoint : Azure.Core.GeoJson.GeoObject - { - public GeoPoint(Azure.Core.GeoJson.GeoPosition position) { } - public GeoPoint(Azure.Core.GeoJson.GeoPosition position, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public GeoPoint(double longitude, double latitude) { } - public GeoPoint(double longitude, double latitude, double? altitude) { } - public Azure.Core.GeoJson.GeoPosition Coordinates { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - } - public sealed partial class GeoPointCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoPointCollection(System.Collections.Generic.IEnumerable points) { } - public GeoPointCollection(System.Collections.Generic.IEnumerable points, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray Coordinates { get { throw null; } } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoPoint this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public sealed partial class GeoPolygon : Azure.Core.GeoJson.GeoObject - { - public GeoPolygon(System.Collections.Generic.IEnumerable rings) { } - public GeoPolygon(System.Collections.Generic.IEnumerable rings, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public GeoPolygon(System.Collections.Generic.IEnumerable positions) { } - public Azure.Core.GeoJson.GeoArray> Coordinates { get { throw null; } } - public Azure.Core.GeoJson.GeoLinearRing OuterRing { get { throw null; } } - public System.Collections.Generic.IReadOnlyList Rings { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - } - public sealed partial class GeoPolygonCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoPolygonCollection(System.Collections.Generic.IEnumerable polygons) { } - public GeoPolygonCollection(System.Collections.Generic.IEnumerable polygons, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray>> Coordinates { get { throw null; } } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoPolygon this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct GeoPosition : System.IEquatable - { - private readonly int _dummyPrimitive; - public GeoPosition(double longitude, double latitude) { throw null; } - public GeoPosition(double longitude, double latitude, double? altitude) { throw null; } - public double? Altitude { get { throw null; } } - public int Count { get { throw null; } } - public double this[int index] { get { throw null; } } - public double Latitude { get { throw null; } } - public double Longitude { get { throw null; } } - public bool Equals(Azure.Core.GeoJson.GeoPosition other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.GeoJson.GeoPosition left, Azure.Core.GeoJson.GeoPosition right) { throw null; } - public static bool operator !=(Azure.Core.GeoJson.GeoPosition left, Azure.Core.GeoJson.GeoPosition right) { throw null; } - public override string ToString() { throw null; } - } -} -namespace Azure.Core.Pipeline -{ - public partial class BearerTokenAuthenticationPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - public BearerTokenAuthenticationPolicy(Azure.Core.TokenCredential credential, System.Collections.Generic.IEnumerable scopes) { } - public BearerTokenAuthenticationPolicy(Azure.Core.TokenCredential credential, string scope) { } - protected void AuthenticateAndAuthorizeRequest(Azure.Core.HttpMessage message, Azure.Core.TokenRequestContext context) { } - protected System.Threading.Tasks.ValueTask AuthenticateAndAuthorizeRequestAsync(Azure.Core.HttpMessage message, Azure.Core.TokenRequestContext context) { throw null; } - protected virtual void AuthorizeRequest(Azure.Core.HttpMessage message) { } - protected virtual System.Threading.Tasks.ValueTask AuthorizeRequestAsync(Azure.Core.HttpMessage message) { throw null; } - protected virtual bool AuthorizeRequestOnChallenge(Azure.Core.HttpMessage message) { throw null; } - protected virtual System.Threading.Tasks.ValueTask AuthorizeRequestOnChallengeAsync(Azure.Core.HttpMessage message) { throw null; } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - } - public sealed partial class DisposableHttpPipeline : Azure.Core.Pipeline.HttpPipeline, System.IDisposable - { - internal DisposableHttpPipeline() : base (default(Azure.Core.Pipeline.HttpPipelineTransport), default(Azure.Core.Pipeline.HttpPipelinePolicy[]), default(Azure.Core.ResponseClassifier)) { } - public void Dispose() { } - } - public partial class HttpClientTransport : Azure.Core.Pipeline.HttpPipelineTransport, System.IDisposable - { - public static readonly Azure.Core.Pipeline.HttpClientTransport Shared; - public HttpClientTransport() { } - public HttpClientTransport(System.Net.Http.HttpClient client) { } - public HttpClientTransport(System.Net.Http.HttpMessageHandler messageHandler) { } - public sealed override Azure.Core.Request CreateRequest() { throw null; } - public void Dispose() { } - public override void Process(Azure.Core.HttpMessage message) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message) { throw null; } - } - public partial class HttpPipeline - { - public HttpPipeline(Azure.Core.Pipeline.HttpPipelineTransport transport, Azure.Core.Pipeline.HttpPipelinePolicy[]? policies = null, Azure.Core.ResponseClassifier? responseClassifier = null) { } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } } - public static System.IDisposable CreateClientRequestIdScope(string? clientRequestId) { throw null; } - public static System.IDisposable CreateHttpMessagePropertiesScope(System.Collections.Generic.IDictionary messageProperties) { throw null; } - public Azure.Core.HttpMessage CreateMessage() { throw null; } - public Azure.Core.HttpMessage CreateMessage(Azure.RequestContext? context) { throw null; } - public Azure.Core.HttpMessage CreateMessage(Azure.RequestContext? context, Azure.Core.ResponseClassifier? classifier = null) { throw null; } - public Azure.Core.Request CreateRequest() { throw null; } - public void Send(Azure.Core.HttpMessage message, System.Threading.CancellationToken cancellationToken) { } - public System.Threading.Tasks.ValueTask SendAsync(Azure.Core.HttpMessage message, System.Threading.CancellationToken cancellationToken) { throw null; } - public Azure.Response SendRequest(Azure.Core.Request request, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.ValueTask SendRequestAsync(Azure.Core.Request request, System.Threading.CancellationToken cancellationToken) { throw null; } - } - public static partial class HttpPipelineBuilder - { - public static Azure.Core.Pipeline.HttpPipeline Build(Azure.Core.ClientOptions options, params Azure.Core.Pipeline.HttpPipelinePolicy[] perRetryPolicies) { throw null; } - public static Azure.Core.Pipeline.DisposableHttpPipeline Build(Azure.Core.ClientOptions options, Azure.Core.Pipeline.HttpPipelinePolicy[] perCallPolicies, Azure.Core.Pipeline.HttpPipelinePolicy[] perRetryPolicies, Azure.Core.Pipeline.HttpPipelineTransportOptions transportOptions, Azure.Core.ResponseClassifier? responseClassifier) { throw null; } - public static Azure.Core.Pipeline.HttpPipeline Build(Azure.Core.ClientOptions options, Azure.Core.Pipeline.HttpPipelinePolicy[] perCallPolicies, Azure.Core.Pipeline.HttpPipelinePolicy[] perRetryPolicies, Azure.Core.ResponseClassifier? responseClassifier) { throw null; } - public static Azure.Core.Pipeline.HttpPipeline Build(Azure.Core.Pipeline.HttpPipelineOptions options) { throw null; } - public static Azure.Core.Pipeline.DisposableHttpPipeline Build(Azure.Core.Pipeline.HttpPipelineOptions options, Azure.Core.Pipeline.HttpPipelineTransportOptions transportOptions) { throw null; } - } - public partial class HttpPipelineOptions - { - public HttpPipelineOptions(Azure.Core.ClientOptions options) { } - public Azure.Core.ClientOptions ClientOptions { get { throw null; } } - public System.Collections.Generic.IList PerCallPolicies { get { throw null; } } - public System.Collections.Generic.IList PerRetryPolicies { get { throw null; } } - public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } - public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } - } - public abstract partial class HttpPipelinePolicy - { - protected HttpPipelinePolicy() { } - public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); - public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); - protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - } - public abstract partial class HttpPipelineSynchronousPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - protected HttpPipelineSynchronousPolicy() { } - public virtual void OnReceivedResponse(Azure.Core.HttpMessage message) { } - public virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - } - public abstract partial class HttpPipelineTransport - { - protected HttpPipelineTransport() { } - public abstract Azure.Core.Request CreateRequest(); - public abstract void Process(Azure.Core.HttpMessage message); - public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message); - } - public partial class HttpPipelineTransportOptions - { - public HttpPipelineTransportOptions() { } - public System.Collections.Generic.IList ClientCertificates { get { throw null; } } - public bool IsClientRedirectEnabled { get { throw null; } set { } } - public System.Func? ServerCertificateCustomValidationCallback { get { throw null; } set { } } - } - public sealed partial class RedirectPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - internal RedirectPolicy() { } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool allowAutoRedirect) { } - } - public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - } - public partial class ServerCertificateCustomValidationArgs - { - public ServerCertificateCustomValidationArgs(System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.X509Certificates.X509Chain? certificateAuthorityChain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { } - public System.Security.Cryptography.X509Certificates.X509Certificate2? Certificate { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509Chain? CertificateAuthorityChain { get { throw null; } } - public System.Net.Security.SslPolicyErrors SslPolicyErrors { get { throw null; } } - } -} -namespace Azure.Core.Serialization -{ - [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerDisplay,nq}")] - public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvider, System.IDisposable - { - internal DynamicData() { } - public void Dispose() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.Serialization.DynamicData? left, object? right) { throw null; } - public static explicit operator System.DateTime (Azure.Core.Serialization.DynamicData value) { throw null; } - public static explicit operator System.DateTimeOffset (Azure.Core.Serialization.DynamicData value) { throw null; } - public static explicit operator System.Guid (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator bool (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator byte (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator decimal (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator double (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator short (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator int (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator long (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator sbyte (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator float (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator string (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator ushort (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator uint (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator ulong (Azure.Core.Serialization.DynamicData value) { throw null; } - public static bool operator !=(Azure.Core.Serialization.DynamicData? left, object? right) { throw null; } - System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(System.Linq.Expressions.Expression parameter) { throw null; } - public override string ToString() { throw null; } - } - public partial interface IMemberNameConverter - { - string? ConvertMemberName(System.Reflection.MemberInfo member); - } - public partial class JsonObjectSerializer : Azure.Core.Serialization.ObjectSerializer, Azure.Core.Serialization.IMemberNameConverter - { - public JsonObjectSerializer() { } - public JsonObjectSerializer(System.Text.Json.JsonSerializerOptions options) { } - public static Azure.Core.Serialization.JsonObjectSerializer Default { get { throw null; } } - string? Azure.Core.Serialization.IMemberNameConverter.ConvertMemberName(System.Reflection.MemberInfo member) { throw null; } - public override object? Deserialize(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; } - public override System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; } - public override void Serialize(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { } - public override System.BinaryData Serialize(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public override System.Threading.Tasks.ValueTask SerializeAsync(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { throw null; } - public override System.Threading.Tasks.ValueTask SerializeAsync(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public enum JsonPropertyNames - { - UseExact = 0, - CamelCase = 1, - } - public abstract partial class ObjectSerializer - { - protected ObjectSerializer() { } - public abstract object? Deserialize(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken); - public abstract System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken); - public abstract void Serialize(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken); - public virtual System.BinaryData Serialize(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public abstract System.Threading.Tasks.ValueTask SerializeAsync(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken); - public virtual System.Threading.Tasks.ValueTask SerializeAsync(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } -} -namespace Azure.Messaging -{ - public partial class CloudEvent - { - public CloudEvent(string source, string type, System.BinaryData? data, string? dataContentType, Azure.Messaging.CloudEventDataFormat dataFormat = Azure.Messaging.CloudEventDataFormat.Binary) { } - public CloudEvent(string source, string type, object? jsonSerializableData, System.Type? dataSerializationType = null) { } - public System.BinaryData? Data { get { throw null; } set { } } - public string? DataContentType { get { throw null; } set { } } - public string? DataSchema { get { throw null; } set { } } - public System.Collections.Generic.IDictionary ExtensionAttributes { get { throw null; } } - public string Id { get { throw null; } set { } } - public string Source { get { throw null; } set { } } - public string? Subject { get { throw null; } set { } } - public System.DateTimeOffset? Time { get { throw null; } set { } } - public string Type { get { throw null; } set { } } - public static Azure.Messaging.CloudEvent? Parse(System.BinaryData json, bool skipValidation = false) { throw null; } - public static Azure.Messaging.CloudEvent[] ParseMany(System.BinaryData json, bool skipValidation = false) { throw null; } - } - public enum CloudEventDataFormat - { - Binary = 0, - Json = 1, - } - public partial class MessageContent - { - public MessageContent() { } - public virtual Azure.Core.ContentType? ContentType { get { throw null; } set { } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - protected virtual Azure.Core.ContentType? ContentTypeCore { get { throw null; } set { } } - public virtual System.BinaryData? Data { get { throw null; } set { } } - public virtual bool IsReadOnly { get { throw null; } } - } -} diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index c7b3c2e8b42b..d9ed2e2954ce 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -232,6 +232,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } @@ -239,13 +240,15 @@ public abstract partial class Response : System.ClientModel.Primitives.PipelineR { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual new System.BinaryData Content { get { throw null; } } + public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + public override System.BinaryData ReadContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask ReadContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } @@ -495,6 +498,7 @@ public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier res public new Azure.Core.Request Request { get { throw null; } } public new Azure.Response Response { get { throw null; } set { } } public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } diff --git a/sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs b/sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs deleted file mode 100644 index 49995b0e56e3..000000000000 --- a/sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs +++ /dev/null @@ -1,1173 +0,0 @@ -namespace Azure -{ - public abstract partial class AsyncPageable : System.Collections.Generic.IAsyncEnumerable where T : notnull - { - protected AsyncPageable() { } - protected AsyncPageable(System.Threading.CancellationToken cancellationToken) { } - protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public abstract System.Collections.Generic.IAsyncEnumerable> AsPages(string? continuationToken = null, int? pageSizeHint = default(int?)); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - public static Azure.AsyncPageable FromPages(System.Collections.Generic.IEnumerable> pages) { throw null; } - public virtual System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - public static partial class AzureCoreExtensions - { - public static dynamic ToDynamicFromJson(this System.BinaryData utf8Json) { throw null; } - public static dynamic ToDynamicFromJson(this System.BinaryData utf8Json, Azure.Core.Serialization.JsonPropertyNames propertyNameFormat, string dateTimeFormat = "o") { throw null; } - public static System.Threading.Tasks.ValueTask ToObjectAsync(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } - public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public partial class AzureKeyCredential - { - public AzureKeyCredential(string key) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public string Key { get { throw null; } } - public void Update(string key) { } - } - public partial class AzureNamedKeyCredential - { - public AzureNamedKeyCredential(string name, string key) { } - public string Name { get { throw null; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public void Deconstruct(out string name, out string key) { throw null; } - public void Update(string name, string key) { } - } - public partial class AzureSasCredential - { - public AzureSasCredential(string signature) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public string Signature { get { throw null; } } - public void Update(string signature) { } - } - [System.FlagsAttribute] - public enum ErrorOptions - { - Default = 0, - NoThrow = 1, - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ETag : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public static readonly Azure.ETag All; - public ETag(string etag) { throw null; } - public bool Equals(Azure.ETag other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public bool Equals(string? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.ETag left, Azure.ETag right) { throw null; } - public static bool operator !=(Azure.ETag left, Azure.ETag right) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string ToString() { throw null; } - public string ToString(string format) { throw null; } - } - public partial class HttpAuthorization - { - public HttpAuthorization(string scheme, string parameter) { } - public string Parameter { get { throw null; } } - public string Scheme { get { throw null; } } - public override string ToString() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct HttpRange : System.IEquatable - { - private readonly int _dummyPrimitive; - public HttpRange(long offset = (long)0, long? length = default(long?)) { throw null; } - public long? Length { get { throw null; } } - public long Offset { get { throw null; } } - public bool Equals(Azure.HttpRange other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.HttpRange left, Azure.HttpRange right) { throw null; } - public static bool operator !=(Azure.HttpRange left, Azure.HttpRange right) { throw null; } - public override string ToString() { throw null; } - } - public partial class JsonPatchDocument - { - public JsonPatchDocument() { } - public JsonPatchDocument(Azure.Core.Serialization.ObjectSerializer serializer) { } - public JsonPatchDocument(System.ReadOnlyMemory rawDocument) { } - public JsonPatchDocument(System.ReadOnlyMemory rawDocument, Azure.Core.Serialization.ObjectSerializer serializer) { } - public void AppendAddRaw(string path, string rawJsonValue) { } - public void AppendAdd(string path, T value) { } - public void AppendCopy(string from, string path) { } - public void AppendMove(string from, string path) { } - public void AppendRemove(string path) { } - public void AppendReplaceRaw(string path, string rawJsonValue) { } - public void AppendReplace(string path, T value) { } - public void AppendTestRaw(string path, string rawJsonValue) { } - public void AppendTest(string path, T value) { } - public System.ReadOnlyMemory ToBytes() { throw null; } - public override string ToString() { throw null; } - } - public partial class MatchConditions - { - public MatchConditions() { } - public Azure.ETag? IfMatch { get { throw null; } set { } } - public Azure.ETag? IfNoneMatch { get { throw null; } set { } } - } - public abstract partial class NullableResponse - { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); - public override string ToString() { throw null; } - } - public abstract partial class Operation - { - protected Operation() { } - public abstract bool HasCompleted { get; } - public abstract string Id { get; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - public abstract Azure.Response UpdateStatus(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public abstract System.Threading.Tasks.ValueTask UpdateStatusAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public virtual Azure.Response WaitForCompletionResponse(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual Azure.Response WaitForCompletionResponse(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual Azure.Response WaitForCompletionResponse(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public abstract partial class Operation : Azure.Operation where T : notnull - { - protected Operation() { } - public abstract bool HasValue { get; } - public abstract T Value { get; } - public virtual Azure.Response WaitForCompletion(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken) { throw null; } - public virtual Azure.Response WaitForCompletion(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual Azure.Response WaitForCompletion(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken) { throw null; } - public virtual System.Threading.Tasks.ValueTask> WaitForCompletionAsync(Azure.Core.DelayStrategy delayStrategy, System.Threading.CancellationToken cancellationToken) { throw null; } - public virtual System.Threading.Tasks.ValueTask> WaitForCompletionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public virtual System.Threading.Tasks.ValueTask> WaitForCompletionAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override System.Threading.Tasks.ValueTask WaitForCompletionResponseAsync(System.TimeSpan pollingInterval, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public abstract partial class PageableOperation : Azure.Operation> where T : notnull - { - protected PageableOperation() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override Azure.AsyncPageable Value { get { throw null; } } - public abstract Azure.Pageable GetValues(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - public abstract Azure.AsyncPageable GetValuesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - } - public abstract partial class Pageable : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable where T : notnull - { - protected Pageable() { } - protected Pageable(System.Threading.CancellationToken cancellationToken) { } - protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public abstract System.Collections.Generic.IEnumerable> AsPages(string? continuationToken = null, int? pageSizeHint = default(int?)); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - public static Azure.Pageable FromPages(System.Collections.Generic.IEnumerable> pages) { throw null; } - public virtual System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - public abstract partial class Page - { - protected Page() { } - public abstract string? ContinuationToken { get; } - public abstract System.Collections.Generic.IReadOnlyList Values { get; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - public static Azure.Page FromValues(System.Collections.Generic.IReadOnlyList values, string? continuationToken, Azure.Response response) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - public partial class RequestConditions : Azure.MatchConditions - { - public RequestConditions() { } - public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } - public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } - } - public partial class RequestContext - { - public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } - public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } - public void AddClassifier(int statusCode, bool isError) { } - public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } - public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } - } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable - { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } - public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } - public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } - } - public abstract partial class Response : System.IDisposable - { - protected Response() { } - public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } - protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); - protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); - public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } - public override string ToString() { throw null; } - protected internal abstract bool TryGetHeader(string name, out string? value); - protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); - } - public sealed partial class ResponseError - { - public ResponseError(string? code, string? message) { } - public string? Code { get { throw null; } } - public string? Message { get { throw null; } } - public override string ToString() { throw null; } - } - public abstract partial class Response : Azure.NullableResponse - { - protected Response() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool HasValue { get { throw null; } } - public override T Value { get { throw null; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static implicit operator T (Azure.Response response) { throw null; } - } - public partial class SyncAsyncEventArgs : System.EventArgs - { - public SyncAsyncEventArgs(bool isRunningSynchronously, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } - public bool IsRunningSynchronously { get { throw null; } } - } - public enum WaitUntil - { - Completed = 0, - Started = 1, - } -} -namespace Azure.Core -{ - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public partial struct AccessToken - { - private object _dummy; - private int _dummyPrimitive; - public AccessToken(string accessToken, System.DateTimeOffset expiresOn) { throw null; } - public System.DateTimeOffset ExpiresOn { get { throw null; } } - public string Token { get { throw null; } } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct AzureLocation : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public AzureLocation(string location) { throw null; } - public AzureLocation(string name, string displayName) { throw null; } - public static Azure.Core.AzureLocation AustraliaCentral { get { throw null; } } - public static Azure.Core.AzureLocation AustraliaCentral2 { get { throw null; } } - public static Azure.Core.AzureLocation AustraliaEast { get { throw null; } } - public static Azure.Core.AzureLocation AustraliaSoutheast { get { throw null; } } - public static Azure.Core.AzureLocation BrazilSouth { get { throw null; } } - public static Azure.Core.AzureLocation BrazilSoutheast { get { throw null; } } - public static Azure.Core.AzureLocation CanadaCentral { get { throw null; } } - public static Azure.Core.AzureLocation CanadaEast { get { throw null; } } - public static Azure.Core.AzureLocation CentralIndia { get { throw null; } } - public static Azure.Core.AzureLocation CentralUS { get { throw null; } } - public static Azure.Core.AzureLocation ChinaEast { get { throw null; } } - public static Azure.Core.AzureLocation ChinaEast2 { get { throw null; } } - public static Azure.Core.AzureLocation ChinaNorth { get { throw null; } } - public static Azure.Core.AzureLocation ChinaNorth2 { get { throw null; } } - public string? DisplayName { get { throw null; } } - public static Azure.Core.AzureLocation EastAsia { get { throw null; } } - public static Azure.Core.AzureLocation EastUS { get { throw null; } } - public static Azure.Core.AzureLocation EastUS2 { get { throw null; } } - public static Azure.Core.AzureLocation FranceCentral { get { throw null; } } - public static Azure.Core.AzureLocation FranceSouth { get { throw null; } } - public static Azure.Core.AzureLocation GermanyCentral { get { throw null; } } - public static Azure.Core.AzureLocation GermanyNorth { get { throw null; } } - public static Azure.Core.AzureLocation GermanyNorthEast { get { throw null; } } - public static Azure.Core.AzureLocation GermanyWestCentral { get { throw null; } } - public static Azure.Core.AzureLocation JapanEast { get { throw null; } } - public static Azure.Core.AzureLocation JapanWest { get { throw null; } } - public static Azure.Core.AzureLocation KoreaCentral { get { throw null; } } - public static Azure.Core.AzureLocation KoreaSouth { get { throw null; } } - public string Name { get { throw null; } } - public static Azure.Core.AzureLocation NorthCentralUS { get { throw null; } } - public static Azure.Core.AzureLocation NorthEurope { get { throw null; } } - public static Azure.Core.AzureLocation NorwayEast { get { throw null; } } - public static Azure.Core.AzureLocation NorwayWest { get { throw null; } } - public static Azure.Core.AzureLocation QatarCentral { get { throw null; } } - public static Azure.Core.AzureLocation SouthAfricaNorth { get { throw null; } } - public static Azure.Core.AzureLocation SouthAfricaWest { get { throw null; } } - public static Azure.Core.AzureLocation SouthCentralUS { get { throw null; } } - public static Azure.Core.AzureLocation SoutheastAsia { get { throw null; } } - public static Azure.Core.AzureLocation SouthIndia { get { throw null; } } - public static Azure.Core.AzureLocation SwedenCentral { get { throw null; } } - public static Azure.Core.AzureLocation SwitzerlandNorth { get { throw null; } } - public static Azure.Core.AzureLocation SwitzerlandWest { get { throw null; } } - public static Azure.Core.AzureLocation UAECentral { get { throw null; } } - public static Azure.Core.AzureLocation UAENorth { get { throw null; } } - public static Azure.Core.AzureLocation UKSouth { get { throw null; } } - public static Azure.Core.AzureLocation UKWest { get { throw null; } } - public static Azure.Core.AzureLocation USDoDCentral { get { throw null; } } - public static Azure.Core.AzureLocation USDoDEast { get { throw null; } } - public static Azure.Core.AzureLocation USGovArizona { get { throw null; } } - public static Azure.Core.AzureLocation USGovIowa { get { throw null; } } - public static Azure.Core.AzureLocation USGovTexas { get { throw null; } } - public static Azure.Core.AzureLocation USGovVirginia { get { throw null; } } - public static Azure.Core.AzureLocation WestCentralUS { get { throw null; } } - public static Azure.Core.AzureLocation WestEurope { get { throw null; } } - public static Azure.Core.AzureLocation WestIndia { get { throw null; } } - public static Azure.Core.AzureLocation WestUS { get { throw null; } } - public static Azure.Core.AzureLocation WestUS2 { get { throw null; } } - public static Azure.Core.AzureLocation WestUS3 { get { throw null; } } - public bool Equals(Azure.Core.AzureLocation other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } - public static implicit operator string (Azure.Core.AzureLocation location) { throw null; } - public static implicit operator Azure.Core.AzureLocation (string location) { throw null; } - public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } - public override string ToString() { throw null; } - } - public abstract partial class ClientOptions - { - protected ClientOptions() { } - protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } - public static Azure.Core.ClientOptions Default { get { throw null; } } - public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } - public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } - public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override string? ToString() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ContentType : System.IEquatable, System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public ContentType(string contentType) { throw null; } - public static Azure.Core.ContentType ApplicationJson { get { throw null; } } - public static Azure.Core.ContentType ApplicationOctetStream { get { throw null; } } - public static Azure.Core.ContentType TextPlain { get { throw null; } } - public bool Equals(Azure.Core.ContentType other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public bool Equals(string? other) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.ContentType left, Azure.Core.ContentType right) { throw null; } - public static implicit operator Azure.Core.ContentType (string contentType) { throw null; } - public static bool operator !=(Azure.Core.ContentType left, Azure.Core.ContentType right) { throw null; } - public override string ToString() { throw null; } - } - public abstract partial class DelayStrategy - { - protected DelayStrategy(System.TimeSpan? maxDelay = default(System.TimeSpan?), double jitterFactor = 0.2) { } - public static Azure.Core.DelayStrategy CreateExponentialDelayStrategy(System.TimeSpan? initialDelay = default(System.TimeSpan?), System.TimeSpan? maxDelay = default(System.TimeSpan?)) { throw null; } - public static Azure.Core.DelayStrategy CreateFixedDelayStrategy(System.TimeSpan? delay = default(System.TimeSpan?)) { throw null; } - public System.TimeSpan GetNextDelay(Azure.Response? response, int retryNumber) { throw null; } - protected abstract System.TimeSpan GetNextDelayCore(Azure.Response? response, int retryNumber); - protected static System.TimeSpan Max(System.TimeSpan val1, System.TimeSpan val2) { throw null; } - protected static System.TimeSpan Min(System.TimeSpan val1, System.TimeSpan val2) { throw null; } - } - public static partial class DelegatedTokenCredential - { - public static Azure.Core.TokenCredential Create(System.Func getToken) { throw null; } - public static Azure.Core.TokenCredential Create(System.Func getToken, System.Func> getTokenAsync) { throw null; } - } - public partial class DiagnosticsOptions - { - protected internal DiagnosticsOptions() { } - public string? ApplicationId { get { throw null; } set { } } - public static string? DefaultApplicationId { get { throw null; } set { } } - public bool IsDistributedTracingEnabled { get { throw null; } set { } } - public bool IsLoggingContentEnabled { get { throw null; } set { } } - public bool IsLoggingEnabled { get { throw null; } set { } } - public bool IsTelemetryEnabled { get { throw null; } set { } } - public int LoggedContentSizeLimit { get { throw null; } set { } } - public System.Collections.Generic.IList LoggedHeaderNames { get { throw null; } } - public System.Collections.Generic.IList LoggedQueryParameters { get { throw null; } } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct HttpHeader : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public HttpHeader(string name, string value) { throw null; } - public string Name { get { throw null; } } - public string Value { get { throw null; } } - public bool Equals(Azure.Core.HttpHeader other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public override string ToString() { throw null; } - public static partial class Common - { - public static readonly Azure.Core.HttpHeader FormUrlEncodedContentType; - public static readonly Azure.Core.HttpHeader JsonAccept; - public static readonly Azure.Core.HttpHeader JsonContentType; - public static readonly Azure.Core.HttpHeader OctetStreamContentType; - } - public static partial class Names - { - public static string Accept { get { throw null; } } - public static string Authorization { get { throw null; } } - public static string ContentDisposition { get { throw null; } } - public static string ContentLength { get { throw null; } } - public static string ContentType { get { throw null; } } - public static string Date { get { throw null; } } - public static string ETag { get { throw null; } } - public static string Host { get { throw null; } } - public static string IfMatch { get { throw null; } } - public static string IfModifiedSince { get { throw null; } } - public static string IfNoneMatch { get { throw null; } } - public static string IfUnmodifiedSince { get { throw null; } } - public static string Prefer { get { throw null; } } - public static string Range { get { throw null; } } - public static string Referer { get { throw null; } } - public static string UserAgent { get { throw null; } } - public static string WwwAuthenticate { get { throw null; } } - public static string XMsDate { get { throw null; } } - public static string XMsRange { get { throw null; } } - public static string XMsRequestId { get { throw null; } } - } - } - public sealed partial class HttpMessage : System.IDisposable - { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } - public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } - public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } - public System.IO.Stream? ExtractResponseContent() { throw null; } - public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } - public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } - } - public enum HttpPipelinePosition - { - PerCall = 0, - PerRetry = 1, - BeforeTransport = 2, - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct MessageProcessingContext - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public int RetryNumber { get { throw null; } set { } } - public System.DateTimeOffset StartTime { get { throw null; } } - } - public static partial class MultipartResponse - { - public static Azure.Response[] Parse(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } - public static System.Threading.Tasks.Task ParseAsync(Azure.Response response, bool expectCrLf, System.Threading.CancellationToken cancellationToken) { throw null; } - } - public abstract partial class Request : System.IDisposable - { - protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } - protected internal abstract void AddHeader(string name, string value); - protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); - protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); - protected internal abstract bool RemoveHeader(string name); - protected internal virtual void SetHeader(string name, string value) { } - protected internal abstract bool TryGetHeader(string name, out string? value); - protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); - } - public abstract partial class RequestContent : System.IDisposable - { - protected RequestContent() { } - public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } - public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } - public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } - public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } - public static Azure.Core.RequestContent Create(System.IO.Stream stream) { throw null; } - public static Azure.Core.RequestContent Create(object serializable) { throw null; } - public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.JsonPropertyNames propertyNameFormat, string dateTimeFormat = "o") { throw null; } - public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } - public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } - public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); - public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } - public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } - public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - } - public abstract partial class RequestFailedDetailsParser - { - protected RequestFailedDetailsParser() { } - public abstract bool TryParse(Azure.Response response, out Azure.ResponseError? error, out System.Collections.Generic.IDictionary? data); - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct RequestHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public void Add(Azure.Core.HttpHeader header) { } - public void Add(string name, string value) { } - public bool Contains(string name) { throw null; } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - public bool Remove(string name) { throw null; } - public void SetValue(string name, string value) { } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - public bool TryGetValue(string name, out string? value) { throw null; } - public bool TryGetValues(string name, out System.Collections.Generic.IEnumerable? values) { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct RequestMethod : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public RequestMethod(string method) { throw null; } - public static Azure.Core.RequestMethod Delete { get { throw null; } } - public static Azure.Core.RequestMethod Get { get { throw null; } } - public static Azure.Core.RequestMethod Head { get { throw null; } } - public string Method { get { throw null; } } - public static Azure.Core.RequestMethod Options { get { throw null; } } - public static Azure.Core.RequestMethod Patch { get { throw null; } } - public static Azure.Core.RequestMethod Post { get { throw null; } } - public static Azure.Core.RequestMethod Put { get { throw null; } } - public static Azure.Core.RequestMethod Trace { get { throw null; } } - public bool Equals(Azure.Core.RequestMethod other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.RequestMethod left, Azure.Core.RequestMethod right) { throw null; } - public static bool operator !=(Azure.Core.RequestMethod left, Azure.Core.RequestMethod right) { throw null; } - public static Azure.Core.RequestMethod Parse(string method) { throw null; } - public override string ToString() { throw null; } - } - public partial class RequestUriBuilder - { - public RequestUriBuilder() { } - protected bool HasPath { get { throw null; } } - protected bool HasQuery { get { throw null; } } - public string? Host { get { throw null; } set { } } - public string Path { get { throw null; } set { } } - public string PathAndQuery { get { throw null; } } - public int Port { get { throw null; } set { } } - public string Query { get { throw null; } set { } } - public string? Scheme { get { throw null; } set { } } - public void AppendPath(System.ReadOnlySpan value, bool escape) { } - public void AppendPath(string value) { } - public void AppendPath(string value, bool escape) { } - public void AppendQuery(System.ReadOnlySpan name, System.ReadOnlySpan value, bool escapeValue) { } - public void AppendQuery(string name, string value) { } - public void AppendQuery(string name, string value, bool escapeValue) { } - public void Reset(System.Uri value) { } - public override string ToString() { throw null; } - public System.Uri ToUri() { throw null; } - } - public sealed partial class ResourceIdentifier : System.IComparable, System.IEquatable - { - public static readonly Azure.Core.ResourceIdentifier Root; - public ResourceIdentifier(string resourceId) { } - public Azure.Core.AzureLocation? Location { get { throw null; } } - public string Name { get { throw null; } } - public Azure.Core.ResourceIdentifier? Parent { get { throw null; } } - public string? Provider { get { throw null; } } - public string? ResourceGroupName { get { throw null; } } - public Azure.Core.ResourceType ResourceType { get { throw null; } } - public string? SubscriptionId { get { throw null; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public Azure.Core.ResourceIdentifier AppendChildResource(string childResourceType, string childResourceName) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public Azure.Core.ResourceIdentifier AppendProviderResource(string providerNamespace, string resourceType, string resourceName) { throw null; } - public int CompareTo(Azure.Core.ResourceIdentifier? other) { throw null; } - public bool Equals(Azure.Core.ResourceIdentifier? other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator >(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator >=(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static implicit operator string (Azure.Core.ResourceIdentifier id) { throw null; } - public static bool operator !=(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator <(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static bool operator <=(Azure.Core.ResourceIdentifier left, Azure.Core.ResourceIdentifier right) { throw null; } - public static Azure.Core.ResourceIdentifier Parse(string input) { throw null; } - public override string ToString() { throw null; } - public static bool TryParse(string? input, out Azure.Core.ResourceIdentifier? result) { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ResourceType : System.IEquatable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public ResourceType(string resourceType) { throw null; } - public string Namespace { get { throw null; } } - public string Type { get { throw null; } } - public bool Equals(Azure.Core.ResourceType other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? other) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public string GetLastType() { throw null; } - public static bool operator ==(Azure.Core.ResourceType left, Azure.Core.ResourceType right) { throw null; } - public static implicit operator string (Azure.Core.ResourceType resourceType) { throw null; } - public static implicit operator Azure.Core.ResourceType (string resourceType) { throw null; } - public static bool operator !=(Azure.Core.ResourceType left, Azure.Core.ResourceType right) { throw null; } - public override string ToString() { throw null; } - } - public abstract partial class ResponseClassificationHandler - { - protected ResponseClassificationHandler() { } - public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); - } - public partial class ResponseClassifier - { - public ResponseClassifier() { } - public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } - public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } - public virtual bool IsRetriableException(System.Exception exception) { throw null; } - public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public int? ContentLength { get { throw null; } } - public long? ContentLengthLong { get { throw null; } } - public string? ContentType { get { throw null; } } - public System.DateTimeOffset? Date { get { throw null; } } - public Azure.ETag? ETag { get { throw null; } } - public string? RequestId { get { throw null; } } - public bool Contains(string name) { throw null; } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - public bool TryGetValue(string name, out string? value) { throw null; } - public bool TryGetValues(string name, out System.Collections.Generic.IEnumerable? values) { throw null; } - } - public enum RetryMode - { - Fixed = 0, - Exponential = 1, - } - public partial class RetryOptions - { - internal RetryOptions() { } - public System.TimeSpan Delay { get { throw null; } set { } } - public System.TimeSpan MaxDelay { get { throw null; } set { } } - public int MaxRetries { get { throw null; } set { } } - public Azure.Core.RetryMode Mode { get { throw null; } set { } } - public System.TimeSpan NetworkTimeout { get { throw null; } set { } } - } - public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier - { - public StatusCodeClassifier(System.ReadOnlySpan successStatusCodes) { } - public override bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } - } - public delegate System.Threading.Tasks.Task SyncAsyncEventHandler(T e) where T : Azure.SyncAsyncEventArgs; - public partial class TelemetryDetails - { - public TelemetryDetails(System.Reflection.Assembly assembly, string? applicationId = null) { } - public string? ApplicationId { get { throw null; } } - public System.Reflection.Assembly Assembly { get { throw null; } } - public void Apply(Azure.Core.HttpMessage message) { } - public override string ToString() { throw null; } - } - public abstract partial class TokenCredential - { - protected TokenCredential() { } - public abstract Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - public abstract System.Threading.Tasks.ValueTask GetTokenAsync(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct TokenRequestContext - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public TokenRequestContext(string[] scopes, string? parentRequestId) { throw null; } - public TokenRequestContext(string[] scopes, string? parentRequestId, string? claims) { throw null; } - public TokenRequestContext(string[] scopes, string? parentRequestId, string? claims, string? tenantId) { throw null; } - public TokenRequestContext(string[] scopes, string? parentRequestId = null, string? claims = null, string? tenantId = null, bool isCaeEnabled = false) { throw null; } - public string? Claims { get { throw null; } } - public bool IsCaeEnabled { get { throw null; } } - public string? ParentRequestId { get { throw null; } } - public string[] Scopes { get { throw null; } } - public string? TenantId { get { throw null; } } - } -} -namespace Azure.Core.Cryptography -{ - public partial interface IKeyEncryptionKey - { - string KeyId { get; } - byte[] UnwrapKey(string algorithm, System.ReadOnlyMemory encryptedKey, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - System.Threading.Tasks.Task UnwrapKeyAsync(string algorithm, System.ReadOnlyMemory encryptedKey, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - byte[] WrapKey(string algorithm, System.ReadOnlyMemory key, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - System.Threading.Tasks.Task WrapKeyAsync(string algorithm, System.ReadOnlyMemory key, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - } - public partial interface IKeyEncryptionKeyResolver - { - Azure.Core.Cryptography.IKeyEncryptionKey Resolve(string keyId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - System.Threading.Tasks.Task ResolveAsync(string keyId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - } -} -namespace Azure.Core.Diagnostics -{ - public partial class AzureEventSourceListener : System.Diagnostics.Tracing.EventListener - { - public const string TraitName = "AzureEventSource"; - public const string TraitValue = "true"; - public AzureEventSourceListener(System.Action log, System.Diagnostics.Tracing.EventLevel level) { } - public static Azure.Core.Diagnostics.AzureEventSourceListener CreateConsoleLogger(System.Diagnostics.Tracing.EventLevel level = System.Diagnostics.Tracing.EventLevel.Informational) { throw null; } - public static Azure.Core.Diagnostics.AzureEventSourceListener CreateTraceLogger(System.Diagnostics.Tracing.EventLevel level = System.Diagnostics.Tracing.EventLevel.Informational) { throw null; } - protected sealed override void OnEventSourceCreated(System.Diagnostics.Tracing.EventSource eventSource) { } - protected sealed override void OnEventWritten(System.Diagnostics.Tracing.EventWrittenEventArgs eventData) { } - } -} -namespace Azure.Core.Extensions -{ - public partial interface IAzureClientBuilder where TOptions : class - { - } - public partial interface IAzureClientFactoryBuilder - { - Azure.Core.Extensions.IAzureClientBuilder RegisterClientFactory(System.Func clientFactory) where TOptions : class; - } - public partial interface IAzureClientFactoryBuilderWithConfiguration : Azure.Core.Extensions.IAzureClientFactoryBuilder - { - Azure.Core.Extensions.IAzureClientBuilder RegisterClientFactory(TConfiguration configuration) where TOptions : class; - } - public partial interface IAzureClientFactoryBuilderWithCredential - { - Azure.Core.Extensions.IAzureClientBuilder RegisterClientFactory(System.Func clientFactory, bool requiresCredential = true) where TOptions : class; - } -} -namespace Azure.Core.GeoJson -{ - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct GeoArray : System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - private readonly object _dummy; - private readonly int _dummyPrimitive; - public int Count { get { throw null; } } - public T this[int index] { get { throw null; } } - public Azure.Core.GeoJson.GeoArray.Enumerator GetEnumerator() { throw null; } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public partial struct Enumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable - { - private object _dummy; - private int _dummyPrimitive; - public T Current { get { throw null; } } - object System.Collections.IEnumerator.Current { get { throw null; } } - public void Dispose() { } - public bool MoveNext() { throw null; } - public void Reset() { } - } - } - public sealed partial class GeoBoundingBox : System.IEquatable - { - public GeoBoundingBox(double west, double south, double east, double north) { } - public GeoBoundingBox(double west, double south, double east, double north, double? minAltitude, double? maxAltitude) { } - public double East { get { throw null; } } - public double this[int index] { get { throw null; } } - public double? MaxAltitude { get { throw null; } } - public double? MinAltitude { get { throw null; } } - public double North { get { throw null; } } - public double South { get { throw null; } } - public double West { get { throw null; } } - public bool Equals(Azure.Core.GeoJson.GeoBoundingBox? other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public override string ToString() { throw null; } - } - public sealed partial class GeoCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoCollection(System.Collections.Generic.IEnumerable geometries) { } - public GeoCollection(System.Collections.Generic.IEnumerable geometries, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoObject this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public sealed partial class GeoLinearRing - { - public GeoLinearRing(System.Collections.Generic.IEnumerable coordinates) { } - public Azure.Core.GeoJson.GeoArray Coordinates { get { throw null; } } - } - public sealed partial class GeoLineString : Azure.Core.GeoJson.GeoObject - { - public GeoLineString(System.Collections.Generic.IEnumerable coordinates) { } - public GeoLineString(System.Collections.Generic.IEnumerable coordinates, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray Coordinates { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - } - public sealed partial class GeoLineStringCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoLineStringCollection(System.Collections.Generic.IEnumerable lines) { } - public GeoLineStringCollection(System.Collections.Generic.IEnumerable lines, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray> Coordinates { get { throw null; } } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoLineString this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public abstract partial class GeoObject - { - internal GeoObject() { } - public Azure.Core.GeoJson.GeoBoundingBox? BoundingBox { get { throw null; } } - public abstract Azure.Core.GeoJson.GeoObjectType Type { get; } - public static Azure.Core.GeoJson.GeoObject Parse(string json) { throw null; } - public override string ToString() { throw null; } - public bool TryGetCustomProperty(string name, out object? value) { throw null; } - } - public enum GeoObjectType - { - Point = 0, - MultiPoint = 1, - Polygon = 2, - MultiPolygon = 3, - LineString = 4, - MultiLineString = 5, - GeometryCollection = 6, - } - public sealed partial class GeoPoint : Azure.Core.GeoJson.GeoObject - { - public GeoPoint(Azure.Core.GeoJson.GeoPosition position) { } - public GeoPoint(Azure.Core.GeoJson.GeoPosition position, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public GeoPoint(double longitude, double latitude) { } - public GeoPoint(double longitude, double latitude, double? altitude) { } - public Azure.Core.GeoJson.GeoPosition Coordinates { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - } - public sealed partial class GeoPointCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoPointCollection(System.Collections.Generic.IEnumerable points) { } - public GeoPointCollection(System.Collections.Generic.IEnumerable points, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray Coordinates { get { throw null; } } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoPoint this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - public sealed partial class GeoPolygon : Azure.Core.GeoJson.GeoObject - { - public GeoPolygon(System.Collections.Generic.IEnumerable rings) { } - public GeoPolygon(System.Collections.Generic.IEnumerable rings, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public GeoPolygon(System.Collections.Generic.IEnumerable positions) { } - public Azure.Core.GeoJson.GeoArray> Coordinates { get { throw null; } } - public Azure.Core.GeoJson.GeoLinearRing OuterRing { get { throw null; } } - public System.Collections.Generic.IReadOnlyList Rings { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - } - public sealed partial class GeoPolygonCollection : Azure.Core.GeoJson.GeoObject, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public GeoPolygonCollection(System.Collections.Generic.IEnumerable polygons) { } - public GeoPolygonCollection(System.Collections.Generic.IEnumerable polygons, Azure.Core.GeoJson.GeoBoundingBox? boundingBox, System.Collections.Generic.IReadOnlyDictionary customProperties) { } - public Azure.Core.GeoJson.GeoArray>> Coordinates { get { throw null; } } - public int Count { get { throw null; } } - public Azure.Core.GeoJson.GeoPolygon this[int index] { get { throw null; } } - public override Azure.Core.GeoJson.GeoObjectType Type { get { throw null; } } - public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct GeoPosition : System.IEquatable - { - private readonly int _dummyPrimitive; - public GeoPosition(double longitude, double latitude) { throw null; } - public GeoPosition(double longitude, double latitude, double? altitude) { throw null; } - public double? Altitude { get { throw null; } } - public int Count { get { throw null; } } - public double this[int index] { get { throw null; } } - public double Latitude { get { throw null; } } - public double Longitude { get { throw null; } } - public bool Equals(Azure.Core.GeoJson.GeoPosition other) { throw null; } - public override bool Equals(object? obj) { throw null; } - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.GeoJson.GeoPosition left, Azure.Core.GeoJson.GeoPosition right) { throw null; } - public static bool operator !=(Azure.Core.GeoJson.GeoPosition left, Azure.Core.GeoJson.GeoPosition right) { throw null; } - public override string ToString() { throw null; } - } -} -namespace Azure.Core.Pipeline -{ - public partial class BearerTokenAuthenticationPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - public BearerTokenAuthenticationPolicy(Azure.Core.TokenCredential credential, System.Collections.Generic.IEnumerable scopes) { } - public BearerTokenAuthenticationPolicy(Azure.Core.TokenCredential credential, string scope) { } - protected void AuthenticateAndAuthorizeRequest(Azure.Core.HttpMessage message, Azure.Core.TokenRequestContext context) { } - protected System.Threading.Tasks.ValueTask AuthenticateAndAuthorizeRequestAsync(Azure.Core.HttpMessage message, Azure.Core.TokenRequestContext context) { throw null; } - protected virtual void AuthorizeRequest(Azure.Core.HttpMessage message) { } - protected virtual System.Threading.Tasks.ValueTask AuthorizeRequestAsync(Azure.Core.HttpMessage message) { throw null; } - protected virtual bool AuthorizeRequestOnChallenge(Azure.Core.HttpMessage message) { throw null; } - protected virtual System.Threading.Tasks.ValueTask AuthorizeRequestOnChallengeAsync(Azure.Core.HttpMessage message) { throw null; } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - } - public sealed partial class DisposableHttpPipeline : Azure.Core.Pipeline.HttpPipeline, System.IDisposable - { - internal DisposableHttpPipeline() : base (default(Azure.Core.Pipeline.HttpPipelineTransport), default(Azure.Core.Pipeline.HttpPipelinePolicy[]), default(Azure.Core.ResponseClassifier)) { } - public void Dispose() { } - } - public partial class HttpClientTransport : Azure.Core.Pipeline.HttpPipelineTransport, System.IDisposable - { - public static readonly Azure.Core.Pipeline.HttpClientTransport Shared; - public HttpClientTransport() { } - public HttpClientTransport(System.Net.Http.HttpClient client) { } - public HttpClientTransport(System.Net.Http.HttpMessageHandler messageHandler) { } - public sealed override Azure.Core.Request CreateRequest() { throw null; } - public void Dispose() { } - public override void Process(Azure.Core.HttpMessage message) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message) { throw null; } - } - public partial class HttpPipeline - { - public HttpPipeline(Azure.Core.Pipeline.HttpPipelineTransport transport, Azure.Core.Pipeline.HttpPipelinePolicy[]? policies = null, Azure.Core.ResponseClassifier? responseClassifier = null) { } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } } - public static System.IDisposable CreateClientRequestIdScope(string? clientRequestId) { throw null; } - public static System.IDisposable CreateHttpMessagePropertiesScope(System.Collections.Generic.IDictionary messageProperties) { throw null; } - public Azure.Core.HttpMessage CreateMessage() { throw null; } - public Azure.Core.HttpMessage CreateMessage(Azure.RequestContext? context) { throw null; } - public Azure.Core.HttpMessage CreateMessage(Azure.RequestContext? context, Azure.Core.ResponseClassifier? classifier = null) { throw null; } - public Azure.Core.Request CreateRequest() { throw null; } - public void Send(Azure.Core.HttpMessage message, System.Threading.CancellationToken cancellationToken) { } - public System.Threading.Tasks.ValueTask SendAsync(Azure.Core.HttpMessage message, System.Threading.CancellationToken cancellationToken) { throw null; } - public Azure.Response SendRequest(Azure.Core.Request request, System.Threading.CancellationToken cancellationToken) { throw null; } - public System.Threading.Tasks.ValueTask SendRequestAsync(Azure.Core.Request request, System.Threading.CancellationToken cancellationToken) { throw null; } - } - public static partial class HttpPipelineBuilder - { - public static Azure.Core.Pipeline.HttpPipeline Build(Azure.Core.ClientOptions options, params Azure.Core.Pipeline.HttpPipelinePolicy[] perRetryPolicies) { throw null; } - public static Azure.Core.Pipeline.DisposableHttpPipeline Build(Azure.Core.ClientOptions options, Azure.Core.Pipeline.HttpPipelinePolicy[] perCallPolicies, Azure.Core.Pipeline.HttpPipelinePolicy[] perRetryPolicies, Azure.Core.Pipeline.HttpPipelineTransportOptions transportOptions, Azure.Core.ResponseClassifier? responseClassifier) { throw null; } - public static Azure.Core.Pipeline.HttpPipeline Build(Azure.Core.ClientOptions options, Azure.Core.Pipeline.HttpPipelinePolicy[] perCallPolicies, Azure.Core.Pipeline.HttpPipelinePolicy[] perRetryPolicies, Azure.Core.ResponseClassifier? responseClassifier) { throw null; } - public static Azure.Core.Pipeline.HttpPipeline Build(Azure.Core.Pipeline.HttpPipelineOptions options) { throw null; } - public static Azure.Core.Pipeline.DisposableHttpPipeline Build(Azure.Core.Pipeline.HttpPipelineOptions options, Azure.Core.Pipeline.HttpPipelineTransportOptions transportOptions) { throw null; } - } - public partial class HttpPipelineOptions - { - public HttpPipelineOptions(Azure.Core.ClientOptions options) { } - public Azure.Core.ClientOptions ClientOptions { get { throw null; } } - public System.Collections.Generic.IList PerCallPolicies { get { throw null; } } - public System.Collections.Generic.IList PerRetryPolicies { get { throw null; } } - public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } - public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } - } - public abstract partial class HttpPipelinePolicy - { - protected HttpPipelinePolicy() { } - public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); - public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); - protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - } - public abstract partial class HttpPipelineSynchronousPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - protected HttpPipelineSynchronousPolicy() { } - public virtual void OnReceivedResponse(Azure.Core.HttpMessage message) { } - public virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - } - public abstract partial class HttpPipelineTransport - { - protected HttpPipelineTransport() { } - public abstract Azure.Core.Request CreateRequest(); - public abstract void Process(Azure.Core.HttpMessage message); - public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message); - } - public partial class HttpPipelineTransportOptions - { - public HttpPipelineTransportOptions() { } - public System.Collections.Generic.IList ClientCertificates { get { throw null; } } - public bool IsClientRedirectEnabled { get { throw null; } set { } } - public System.Func? ServerCertificateCustomValidationCallback { get { throw null; } set { } } - } - public sealed partial class RedirectPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - internal RedirectPolicy() { } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool allowAutoRedirect) { } - } - public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy - { - public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } - public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } - public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - } - public partial class ServerCertificateCustomValidationArgs - { - public ServerCertificateCustomValidationArgs(System.Security.Cryptography.X509Certificates.X509Certificate2? certificate, System.Security.Cryptography.X509Certificates.X509Chain? certificateAuthorityChain, System.Net.Security.SslPolicyErrors sslPolicyErrors) { } - public System.Security.Cryptography.X509Certificates.X509Certificate2? Certificate { get { throw null; } } - public System.Security.Cryptography.X509Certificates.X509Chain? CertificateAuthorityChain { get { throw null; } } - public System.Net.Security.SslPolicyErrors SslPolicyErrors { get { throw null; } } - } -} -namespace Azure.Core.Serialization -{ - [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerDisplay,nq}")] - public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvider, System.IDisposable - { - internal DynamicData() { } - public void Dispose() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override bool Equals(object? obj) { throw null; } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public override int GetHashCode() { throw null; } - public static bool operator ==(Azure.Core.Serialization.DynamicData? left, object? right) { throw null; } - public static explicit operator System.DateTime (Azure.Core.Serialization.DynamicData value) { throw null; } - public static explicit operator System.DateTimeOffset (Azure.Core.Serialization.DynamicData value) { throw null; } - public static explicit operator System.Guid (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator bool (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator byte (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator decimal (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator double (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator short (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator int (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator long (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator sbyte (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator float (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator string (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator ushort (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator uint (Azure.Core.Serialization.DynamicData value) { throw null; } - public static implicit operator ulong (Azure.Core.Serialization.DynamicData value) { throw null; } - public static bool operator !=(Azure.Core.Serialization.DynamicData? left, object? right) { throw null; } - System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(System.Linq.Expressions.Expression parameter) { throw null; } - public override string ToString() { throw null; } - } - public partial interface IMemberNameConverter - { - string? ConvertMemberName(System.Reflection.MemberInfo member); - } - public partial class JsonObjectSerializer : Azure.Core.Serialization.ObjectSerializer, Azure.Core.Serialization.IMemberNameConverter - { - public JsonObjectSerializer() { } - public JsonObjectSerializer(System.Text.Json.JsonSerializerOptions options) { } - public static Azure.Core.Serialization.JsonObjectSerializer Default { get { throw null; } } - string? Azure.Core.Serialization.IMemberNameConverter.ConvertMemberName(System.Reflection.MemberInfo member) { throw null; } - public override object? Deserialize(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; } - public override System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; } - public override void Serialize(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { } - public override System.BinaryData Serialize(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public override System.Threading.Tasks.ValueTask SerializeAsync(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { throw null; } - public override System.Threading.Tasks.ValueTask SerializeAsync(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public enum JsonPropertyNames - { - UseExact = 0, - CamelCase = 1, - } - public abstract partial class ObjectSerializer - { - protected ObjectSerializer() { } - public abstract object? Deserialize(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken); - public abstract System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken); - public abstract void Serialize(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken); - public virtual System.BinaryData Serialize(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public abstract System.Threading.Tasks.ValueTask SerializeAsync(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken); - public virtual System.Threading.Tasks.ValueTask SerializeAsync(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } -} -namespace Azure.Messaging -{ - public partial class CloudEvent - { - public CloudEvent(string source, string type, System.BinaryData? data, string? dataContentType, Azure.Messaging.CloudEventDataFormat dataFormat = Azure.Messaging.CloudEventDataFormat.Binary) { } - public CloudEvent(string source, string type, object? jsonSerializableData, System.Type? dataSerializationType = null) { } - public System.BinaryData? Data { get { throw null; } set { } } - public string? DataContentType { get { throw null; } set { } } - public string? DataSchema { get { throw null; } set { } } - public System.Collections.Generic.IDictionary ExtensionAttributes { get { throw null; } } - public string Id { get { throw null; } set { } } - public string Source { get { throw null; } set { } } - public string? Subject { get { throw null; } set { } } - public System.DateTimeOffset? Time { get { throw null; } set { } } - public string Type { get { throw null; } set { } } - public static Azure.Messaging.CloudEvent? Parse(System.BinaryData json, bool skipValidation = false) { throw null; } - public static Azure.Messaging.CloudEvent[] ParseMany(System.BinaryData json, bool skipValidation = false) { throw null; } - } - public enum CloudEventDataFormat - { - Binary = 0, - Json = 1, - } - public partial class MessageContent - { - public MessageContent() { } - public virtual Azure.Core.ContentType? ContentType { get { throw null; } set { } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - protected virtual Azure.Core.ContentType? ContentTypeCore { get { throw null; } set { } } - public virtual System.BinaryData? Data { get { throw null; } set { } } - public virtual bool IsReadOnly { get { throw null; } } - } -} diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index a850bca34665..0d825ec9eed9 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -232,6 +232,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } @@ -239,13 +240,15 @@ public abstract partial class Response : System.ClientModel.Primitives.PipelineR { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual new System.BinaryData Content { get { throw null; } } + public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected internal abstract bool ContainsHeader(string name); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected override System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore() { throw null; } + public override System.BinaryData ReadContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask ReadContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected sealed override void SetIsErrorCore(bool isError) { } public override string ToString() { throw null; } @@ -495,6 +498,7 @@ public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier res public new Azure.Core.Request Request { get { throw null; } } public new Azure.Response Response { get { throw null; } set { } } public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } diff --git a/sdk/core/Azure.Core/samples/Configuration.md b/sdk/core/Azure.Core/samples/Configuration.md index 1aa9263af641..3c06406e524c 100644 --- a/sdk/core/Azure.Core/samples/Configuration.md +++ b/sdk/core/Azure.Core/samples/Configuration.md @@ -40,6 +40,7 @@ internal class GlobalTimeoutRetryPolicy : RetryPolicy { return ShouldRetryInternalAsync(message, exception, false).EnsureCompleted(); } + protected override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) { return ShouldRetryInternalAsync(message, exception, true); diff --git a/sdk/core/Azure.Core/src/ClientOptions.cs b/sdk/core/Azure.Core/src/ClientOptions.cs index cf302df226f5..b4f46998b138 100644 --- a/sdk/core/Azure.Core/src/ClientOptions.cs +++ b/sdk/core/Azure.Core/src/ClientOptions.cs @@ -14,6 +14,8 @@ namespace Azure.Core /// public abstract class ClientOptions : ClientPipelineOptions { + internal static readonly TimeSpan DefaultNetworkTimeout = TimeSpan.FromSeconds(100); + private HttpPipelineTransport _transport; internal bool IsCustomTransportSet { get; private set; } diff --git a/sdk/core/Azure.Core/src/HttpMessage.cs b/sdk/core/Azure.Core/src/HttpMessage.cs index bcf04d0700ce..803fdc977e12 100644 --- a/sdk/core/Azure.Core/src/HttpMessage.cs +++ b/sdk/core/Azure.Core/src/HttpMessage.cs @@ -26,6 +26,7 @@ public HttpMessage(Request request, ResponseClassifier responseClassifier) Argument.AssertNotNull(request, nameof(request)); ResponseClassifier = responseClassifier; + NetworkTimeout = request.NetworkTimeout ?? ClientOptions.DefaultNetworkTimeout; } /// @@ -44,7 +45,10 @@ public HttpMessage(Request request, ResponseClassifier responseClassifier) if (base.Response is null) { #pragma warning disable CA1065 // Do not raise exceptions in unexpected locations - throw new InvalidOperationException("Response was not set, make sure SendAsync was called"); + throw new InvalidOperationException($"{nameof(Response)} is not set on this message. " + + "This is may be because the message was not sent via pipeline.Send, " + + "the pipeline transport did not populate the response, or because " + + $"{nameof(ExtractResponse)} was called."); #pragma warning restore CA1065 // Do not raise exceptions in unexpected locations } return (Response)base.Response; @@ -155,15 +159,14 @@ public void SetProperty(string name, object value) /// Exists as a private key entry into the property bag for stashing string keyed entries in the Type keyed dictionary. /// private class MessagePropertyKey { } - #endregion /// - /// Returns the response content stream and releases it ownership to the caller. - /// - /// After calling this method, any attempt to use the - /// or - /// properties on will result in an exception being thrown. + /// Returns the response content stream and releases its ownership to the caller. + /// After this method has been called, any use of the + /// or + /// properties on this message will result in an + /// being thrown. /// /// The content stream, or null if /// did not have content set. @@ -186,6 +189,15 @@ private class MessagePropertyKey { } } } + /// + /// Returns the value of the property and + /// transfers dispose ownership of the response to the caller. After + /// calling this method, the property will be + /// null and the caller will be responsible for disposing the returned + /// value, which may hold a live network stream. + /// + public new Response? ExtractResponse() => (Response?)base.ExtractResponse(); + private class ResponseShouldNotBeUsedStream : Stream { public Stream Original { get; } diff --git a/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs b/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs index 50087757232c..9d1410e65b11 100644 --- a/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs +++ b/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs @@ -13,6 +13,9 @@ namespace Azure.Core.Buffers { internal static class AzureBaseBuffersExtensions { + // Same value as Stream.CopyTo uses by default + private const int DefaultCopyBufferSize = 81920; + public static async Task WriteAsync(this Stream stream, ReadOnlyMemory buffer, CancellationToken cancellation = default) { Argument.AssertNotNull(stream, nameof(stream)); @@ -87,5 +90,82 @@ public static async Task WriteAsync(this Stream stream, ReadOnlySequence b ArrayPool.Shared.Return(array); } } + + public static async Task CopyToAsync(this Stream source, Stream destination, CancellationToken cancellationToken) + { + //using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + //cts.CancelAfter(timeout); + + //// If cancellation is possible (whether due to network timeout or a user cancellation token being passed), then + //// register callback to dispose the stream on cancellation. + //if (timeout != Timeout.InfiniteTimeSpan || cancellationToken.CanBeCanceled) + //{ + // cts.Token.Register(state => ((Stream?)state)?.Dispose(), source); + //} + + byte[] buffer = ArrayPool.Shared.Rent(DefaultCopyBufferSize); + + try + { + while (true) + { +#pragma warning disable CA1835 // ReadAsync(Memory<>) overload is not available in all targets + int bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); +#pragma warning restore // ReadAsync(Memory<>) overload is not available in all targets + if (bytesRead == 0) + break; + await destination.WriteAsync(new ReadOnlyMemory(buffer, 0, bytesRead), cancellationToken).ConfigureAwait(false); + } + } + //catch (Exception ex) when (ex is ObjectDisposedException + // or IOException + // or OperationCanceledException + // or NotSupportedException) + //{ + // CancellationHelper.ThrowIfCancellationRequestedOrTimeout(cancellationToken, cts.Token, ex, timeout); + // throw; + //} + finally + { + ArrayPool.Shared.Return(buffer); + } + } + + public static void CopyTo(this Stream source, Stream destination, CancellationToken cancellationToken) + { + //using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + //cts.CancelAfter(timeout); + + //// If cancellation is possible (whether due to network timeout or a user cancellation token being passed), then + //// register callback to dispose the stream on cancellation. + //if (timeout != Timeout.InfiniteTimeSpan || cancellationToken.CanBeCanceled) + //{ + // cts.Token.Register(state => ((Stream?)state)?.Dispose(), source); + //} + + byte[] buffer = ArrayPool.Shared.Rent(DefaultCopyBufferSize); + + try + { + int read; + while ((read = source.Read(buffer, 0, buffer.Length)) != 0) + { + cancellationToken.ThrowIfCancellationRequested(); + destination.Write(buffer, 0, read); + } + } + //catch (Exception ex) when (ex is ObjectDisposedException + // or IOException + // or OperationCanceledException + // or NotSupportedException) + //{ + // CancellationHelper.ThrowIfCancellationRequestedOrTimeout(cancellationToken, cts.Token, ex, timeout); + // throw; + //} + finally + { + ArrayPool.Shared.Return(buffer); + } + } } } diff --git a/sdk/core/Azure.Core/src/Internal/ClientModelPolicyCollectionAdapter.cs b/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs similarity index 92% rename from sdk/core/Azure.Core/src/Internal/ClientModelPolicyCollectionAdapter.cs rename to sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs index 963a0b350734..28669ffd0e34 100644 --- a/sdk/core/Azure.Core/src/Internal/ClientModelPolicyCollectionAdapter.cs +++ b/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs @@ -18,12 +18,12 @@ namespace Azure.Core.Pipeline /// hold System.ClientModel policies internally and call their process methods /// in a way that will continue passing control down the chain of policies. /// - internal struct ClientModelPolicyCollectionAdapter : IReadOnlyList + internal struct AzureCorePipelineProcessor : IReadOnlyList { private readonly ReadOnlyMemory _policies; private PolicyEnumerator? _enumerator; - public ClientModelPolicyCollectionAdapter(ReadOnlyMemory policies) + public AzureCorePipelineProcessor(ReadOnlyMemory policies) => _policies = policies; public ReadOnlyMemory Policies diff --git a/sdk/core/Azure.Core/src/Pipeline/DisposableHttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/DisposableHttpPipeline.cs index e21aebdc4abc..d18ffa921ff1 100644 --- a/sdk/core/Azure.Core/src/Pipeline/DisposableHttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/DisposableHttpPipeline.cs @@ -24,8 +24,9 @@ public sealed class DisposableHttpPipeline : HttpPipeline, IDisposable /// Policies to be invoked as part of the pipeline in order. /// The response classifier to be used in invocations. /// - internal DisposableHttpPipeline(HttpPipelineTransport transport, int perCallIndex, int perRetryIndex, HttpPipelinePolicy[] policies, ResponseClassifier responseClassifier, bool isTransportOwnedInternally) - : base(transport, perCallIndex, perRetryIndex, policies, responseClassifier) + /// + internal DisposableHttpPipeline(HttpPipelineTransport transport, int perCallIndex, int perRetryIndex, HttpPipelinePolicy[] policies, ResponseClassifier responseClassifier, bool isTransportOwnedInternally, TimeSpan networkTimeout) + : base(transport, perCallIndex, perRetryIndex, policies, responseClassifier, networkTimeout) { this.isTransportOwnedInternally = isTransportOwnedInternally; } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index eb4e8bfad6bc..5cc25119df3a 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -17,9 +17,9 @@ public partial class HttpClientTransport /// and to add /// features specific to Azure, such as . /// - private class ClientModelHttpClientTransport : HttpClientPipelineTransport + private class AzureCoreHttpPipelineTransport : HttpClientPipelineTransport { - public ClientModelHttpClientTransport(HttpClient client) : base(client) + public AzureCoreHttpPipelineTransport(HttpClient client) : base(client) { } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs index 604df526b3e3..337a87892436 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs @@ -1,11 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.ClientModel.Primitives; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; namespace Azure.Core.Pipeline { @@ -41,6 +44,21 @@ public override Stream? ContentStream set => _pipelineResponse.ContentStream = value; } + public override BinaryData Content + { + get + { + ResetContentStreamPosition(_pipelineResponse); + return _pipelineResponse.Content; + } + } + + public override BinaryData ReadContent(CancellationToken cancellationToken = default) + => _pipelineResponse.ReadContent(cancellationToken); + + public override async ValueTask ReadContentAsync(CancellationToken cancellationToken = default) + => await base.ReadContentAsync(cancellationToken).ConfigureAwait(false); + protected internal override bool ContainsHeader(string name) => _pipelineResponse.Headers.TryGetValue(name, out _); @@ -61,8 +79,24 @@ protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(tr public override void Dispose() { PipelineResponse response = _pipelineResponse; + ResetContentStreamPosition(response); response?.Dispose(); } + + private void ResetContentStreamPosition(PipelineResponse response) + { + if (response.ContentStream is MemoryStream stream && stream.Position != 0) + { + // Azure.Core Response has a contract that ContentStream can be read + // without setting position back to 0. This means if ReadContent is + // called after such a read, the buffer will contain empty BinaryData. + + // So that the ClientModel response implementations don't throw, + // set the position back to 0 if Azure.Core Response default + // ReadContent was called. + stream.Position = 0; + } + } } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs index f4d61707cd17..18c1bc678b32 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs @@ -26,7 +26,7 @@ public partial class HttpClientTransport : HttpPipelineTransport, IDisposable // The transport's private HttpClient is internal because it is used by tests. internal HttpClient Client { get; } - private readonly ClientModelHttpClientTransport _transport; + private readonly AzureCoreHttpPipelineTransport _transport; /// /// Creates a new instance using default configuration. @@ -52,7 +52,7 @@ public HttpClientTransport(HttpClient client) { Client = client ?? throw new ArgumentNullException(nameof(client)); - _transport = new ClientModelHttpClientTransport(client); + _transport = new AzureCoreHttpPipelineTransport(client); } /// @@ -99,11 +99,11 @@ public override async ValueTask ProcessAsync(HttpMessage message) { if (message.HasResponse) { - throw new RequestFailedException(message.Response, e.InnerException); + throw await RequestFailedException.CreateAsync(message.Response, innerException: e.InnerException).ConfigureAwait(false); } else { - throw new RequestFailedException(e.Message, e.InnerException); + throw new RequestFailedException(e.Message, innerException: e.InnerException); } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs index 221270684e8a..61bb9850a61f 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs @@ -40,6 +40,8 @@ public class HttpPipeline /// private readonly int _perRetryIndex; + private readonly TimeSpan _networkTimeout; + /// /// Creates a new instance of with the provided transport, policies and response classifier. /// @@ -59,6 +61,7 @@ public HttpPipeline(HttpPipelineTransport transport, HttpPipelinePolicy[]? polic policies.CopyTo(all, 0); _pipeline = all; + _networkTimeout = ClientOptions.DefaultNetworkTimeout; } internal HttpPipeline( @@ -66,7 +69,8 @@ internal HttpPipeline( int perCallIndex, int perRetryIndex, HttpPipelinePolicy[] pipeline, - ResponseClassifier responseClassifier) + ResponseClassifier responseClassifier, + TimeSpan? networkTimeout) { ResponseClassifier = responseClassifier ?? throw new ArgumentNullException(nameof(responseClassifier)); @@ -77,6 +81,9 @@ internal HttpPipeline( _perCallIndex = perCallIndex; _perRetryIndex = perRetryIndex; + + _networkTimeout = networkTimeout ?? ClientOptions.DefaultNetworkTimeout; + _internallyConstructed = true; } @@ -85,14 +92,22 @@ internal HttpPipeline( /// /// The request. public Request CreateRequest() - => _transport.CreateRequest(); + { + Request request = _transport.CreateRequest(); + request.NetworkTimeout = _networkTimeout; + return request; + } /// /// Creates a new instance. /// /// The message. public HttpMessage CreateMessage() - => new(CreateRequest(), ResponseClassifier); + { + Request request = CreateRequest(); + HttpMessage message = new(request, ResponseClassifier); + return message; + } /// /// @@ -109,7 +124,8 @@ public HttpMessage CreateMessage(RequestContext? context) /// The message. public HttpMessage CreateMessage(RequestContext? context, ResponseClassifier? classifier = default) { - HttpMessage message = new(CreateRequest(), classifier ?? ResponseClassifier); + Request request = CreateRequest(); + HttpMessage message = new(request, classifier ?? ResponseClassifier); if (context != null) { @@ -134,6 +150,11 @@ public ValueTask SendAsync(HttpMessage message, CancellationToken cancellationTo { message.SetCancellationToken(cancellationToken); message.ProcessingStartTime = DateTimeOffset.UtcNow; + + // We must set NetworkTimeout here because the documentation for + // HttpMessage states that if a user sets this value to null, the + // pipeline will use the value set on ClientOptions. + message.NetworkTimeout ??= _networkTimeout; AddHttpMessageProperties(message); if (message.Policies == null || message.Policies.Count == 0) @@ -169,6 +190,7 @@ public void Send(HttpMessage message, CancellationToken cancellationToken) { message.SetCancellationToken(cancellationToken); message.ProcessingStartTime = DateTimeOffset.UtcNow; + message.NetworkTimeout ??= _networkTimeout; AddHttpMessageProperties(message); if (message.Policies == null || message.Policies.Count == 0) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs index e84ee002ae01..d218be0c7b82 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs @@ -43,7 +43,7 @@ public static HttpPipeline Build( ((List)pipelineOptions.PerRetryPolicies).AddRange(perRetryPolicies); var result = BuildInternal(pipelineOptions, null); - return new HttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier); + return new HttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier, result.NetworkTimeout); } /// @@ -63,7 +63,7 @@ public static DisposableHttpPipeline Build(ClientOptions options, HttpPipelinePo ((List)pipelineOptions.PerCallPolicies).AddRange(perCallPolicies); ((List)pipelineOptions.PerRetryPolicies).AddRange(perRetryPolicies); var result = BuildInternal(pipelineOptions, transportOptions); - return new DisposableHttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier, result.IsTransportOwned); + return new DisposableHttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier, result.IsTransportOwned, result.NetworkTimeout); } /// @@ -74,7 +74,7 @@ public static DisposableHttpPipeline Build(ClientOptions options, HttpPipelinePo public static HttpPipeline Build(HttpPipelineOptions options) { var result = BuildInternal(options, null); - return new HttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier); + return new HttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier, result.NetworkTimeout); } /// @@ -87,17 +87,17 @@ public static DisposableHttpPipeline Build(HttpPipelineOptions options, HttpPipe { Argument.AssertNotNull(transportOptions, nameof(transportOptions)); var result = BuildInternal(options, transportOptions); - return new DisposableHttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier, result.IsTransportOwned); + return new DisposableHttpPipeline(result.Transport, result.PerCallIndex, result.PerRetryIndex, result.Policies, result.Classifier, result.IsTransportOwned, result.NetworkTimeout); } - internal static (ResponseClassifier Classifier, HttpPipelineTransport Transport, int PerCallIndex, int PerRetryIndex, HttpPipelinePolicy[] Policies, bool IsTransportOwned) BuildInternal( + internal static (ResponseClassifier Classifier, HttpPipelineTransport Transport, int PerCallIndex, int PerRetryIndex, HttpPipelinePolicy[] Policies, bool IsTransportOwned, TimeSpan NetworkTimeout) BuildInternal( HttpPipelineOptions buildOptions, HttpPipelineTransportOptions? defaultTransportOptions) { Argument.AssertNotNull(buildOptions.PerCallPolicies, nameof(buildOptions.PerCallPolicies)); Argument.AssertNotNull(buildOptions.PerRetryPolicies, nameof(buildOptions.PerRetryPolicies)); - var policies = new List(8 + + var policies = new List(7 + (buildOptions.ClientOptions.Policies?.Count ?? 0) + buildOptions.PerCallPolicies.Count + buildOptions.PerRetryPolicies.Count); @@ -181,8 +181,6 @@ void AddNonNullPolicies(HttpPipelinePolicy[] policiesToAdd) policies.Add(new LoggingPolicy(diagnostics.IsLoggingContentEnabled, diagnostics.LoggedContentSizeLimit, sanitizer, assemblyName)); } - policies.Add(new ResponseBodyPolicy(buildOptions.ClientOptions.Retry.NetworkTimeout)); - policies.Add(new RequestActivityPolicy(isDistributedTracingEnabled, ClientDiagnostics.GetResourceProviderNamespace(buildOptions.ClientOptions.GetType().Assembly), sanitizer)); AddUserPolicies(HttpPipelinePosition.BeforeTransport); @@ -209,7 +207,7 @@ void AddNonNullPolicies(HttpPipelinePolicy[] policiesToAdd) buildOptions.ResponseClassifier ??= ResponseClassifier.Shared; - return (buildOptions.ResponseClassifier, transport, perCallIndex, perRetryIndex, policies.ToArray(), isTransportInternallyCreated); + return (buildOptions.ResponseClassifier, transport, perCallIndex, perRetryIndex, policies.ToArray(), isTransportInternallyCreated, buildOptions.ClientOptions.Retry.NetworkTimeout); } // internal for testing diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs index 0b6a12f43ffe..0e5a37ed88e9 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs @@ -64,7 +64,7 @@ public sealed override async ValueTask ProcessAsync(PipelineMessage message, IRe throw new InvalidOperationException($"Invalid type for message: '{message?.GetType()}'"); } - if (pipeline is not ClientModelPolicyCollectionAdapter processor) + if (pipeline is not AzureCorePipelineProcessor processor) { throw new InvalidOperationException($"Invalid type for pipeline: '{pipeline?.GetType()}'"); } @@ -89,7 +89,7 @@ public sealed override void Process(PipelineMessage message, IReadOnlyList /// Represents an HTTP pipeline transport used to send HTTP requests and receive responses. /// - public abstract class HttpPipelineTransport + public abstract partial class HttpPipelineTransport { + private readonly PipelineTransport _transport; + + /// + /// TBD. + /// + protected HttpPipelineTransport() + { + _transport = new AzureCorePipelineTransport(this); + } + + internal void ProcessInternal(HttpMessage message) + { + _transport.Process(message); + } + + internal async ValueTask ProcessInternalAsync(HttpMessage message) + { + await _transport.ProcessAsync(message).ConfigureAwait(false); + } + /// /// Sends the request contained by the and sets the property to received response synchronously. /// diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs index f3153bbe9011..77b0501fc8fb 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs @@ -328,6 +328,8 @@ public override Stream? ContentStream } } + // TODO: Implement Content and ReadContent + public override string ClientRequestId { get; set; } public override void Dispose() diff --git a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs index 49f5dfce21f9..e2152809a849 100644 --- a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs @@ -24,7 +24,7 @@ public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory { Debug.Assert(pipeline.IsEmpty); - await _transport.ProcessAsync(message).ConfigureAwait(false); + await _transport.ProcessInternalAsync(message).ConfigureAwait(false); message.Response.RequestFailedDetailsParser = _errorParser; message.Response.Sanitizer = _sanitizer; @@ -35,7 +35,7 @@ public override void Process(HttpMessage message, ReadOnlyMemory - /// Pipeline policy to buffer response content or add a timeout to response content managed by the client - /// - internal class ResponseBodyPolicy : HttpPipelinePolicy - { - private readonly ResponseBufferingPolicy _policy; - private readonly TimeSpan _networkTimeout; - - public ResponseBodyPolicy(TimeSpan networkTimeout) - { - _policy = new ResponseBufferingPolicy(); - _networkTimeout = networkTimeout; - } - - public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory pipeline) - => await ProcessSyncOrAsync(message, pipeline, async: true).ConfigureAwait(false); - - public override void Process(HttpMessage message, ReadOnlyMemory pipeline) - => ProcessSyncOrAsync(message, pipeline, async: false).EnsureCompleted(); - - private async ValueTask ProcessSyncOrAsync(HttpMessage message, ReadOnlyMemory pipeline, bool async) - { - ClientModelPolicyCollectionAdapter processor = new(pipeline); - - // Get the network timeout for this particular invocation of the pipeline. - // We either use the default that the policy was constructed with at - // pipeline-creation time, or we get an override value from the message that - // we use for the duration of this invocation only. - message.NetworkTimeout ??= _networkTimeout; - TimeSpan invocationNetworkTimeout = (TimeSpan)message.NetworkTimeout!; - - try - { - if (async) - { - await _policy.ProcessAsync(message, processor, -1).ConfigureAwait(false); - } - else - { - _policy.Process(message, processor, -1); - } - } - catch (TaskCanceledException e) - { - if (e.Message.Contains("The operation was cancelled because it exceeded the configured timeout")) - { - string exceptionMessage = e.Message + - $"Network timeout can be adjusted in {nameof(ClientOptions)}.{nameof(ClientOptions.Retry)}.{nameof(RetryOptions.NetworkTimeout)}."; -#if NETCOREAPP2_1_OR_GREATER - throw new TaskCanceledException(exceptionMessage, e.InnerException, e.CancellationToken); -#else - throw new TaskCanceledException(exceptionMessage, e.InnerException); -#endif - } - else - { - throw e; - } - } - } - - /// Throws a cancellation exception if cancellation has been requested via or . - /// The customer provided token. - /// The linked token that is cancelled on timeout provided token. - /// The inner exception to use. - /// The timeout used for the operation. -#pragma warning disable CA1068 // Cancellation token has to be the last parameter - internal static void ThrowIfCancellationRequestedOrTimeout(CancellationToken originalToken, CancellationToken timeoutToken, Exception? inner, TimeSpan timeout) -#pragma warning restore CA1068 - { - CancellationHelper.ThrowIfCancellationRequested(originalToken); - - if (timeoutToken.IsCancellationRequested) - { - throw CancellationHelper.CreateOperationCanceledException( - inner, - timeoutToken, - $"The operation was cancelled because it exceeded the configured timeout of {timeout:g}. " + - $"Network timeout can be adjusted in {nameof(ClientOptions)}.{nameof(ClientOptions.Retry)}.{nameof(RetryOptions.NetworkTimeout)}."); - } - } - } -} diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs index c9b8e5da59d0..09230a634cdb 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs @@ -15,7 +15,7 @@ public partial class RetryPolicy /// /// Adds Azure.Core features to the System.ClientModel retry policy. /// - internal class ClientModelRetryPolicy : ClientRetryPolicy + internal class AzureCoreRetryPolicy : ClientRetryPolicy { private readonly RetryPolicy _pipelinePolicy; private readonly DelayStrategy _delayStrategy; @@ -24,7 +24,7 @@ internal class ClientModelRetryPolicy : ClientRetryPolicy private long _afterProcess; private double _elapsedTime; - public ClientModelRetryPolicy(int maxRetries, DelayStrategy delay, RetryPolicy policy) + public AzureCoreRetryPolicy(int maxRetries, DelayStrategy delay, RetryPolicy policy) : base(maxRetries) { _delayStrategy = delay; diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs index 081c391f055f..b1873a04c6a5 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs @@ -15,7 +15,7 @@ public partial class RetryPolicy : HttpPipelinePolicy { private readonly int _maxRetries; private readonly DelayStrategy _delayStrategy; - private readonly ClientModelRetryPolicy _policy; + private readonly AzureCoreRetryPolicy _policy; /// /// Initializes a new instance of the class. @@ -27,7 +27,7 @@ public RetryPolicy(int maxRetries = RetryOptions.DefaultMaxRetries, DelayStrateg _maxRetries = maxRetries; _delayStrategy = delayStrategy ?? DelayStrategy.CreateExponentialDelayStrategy(); - _policy = new ClientModelRetryPolicy(maxRetries, _delayStrategy, this); + _policy = new AzureCoreRetryPolicy(maxRetries, _delayStrategy, this); } /// @@ -53,7 +53,7 @@ public override void Process(HttpMessage message, ReadOnlyMemory pipeline, bool async) { - ClientModelPolicyCollectionAdapter processor = new(pipeline); + AzureCorePipelineProcessor processor = new(pipeline); try { diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index c0e3ceb361f3..d71dde70c4ee 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -73,6 +73,8 @@ public virtual string ClientRequestId /// public new RequestHeaders Headers => new(this); + internal TimeSpan? NetworkTimeout { get; set; } + #region Overrides for "Core" methods from the PipelineRequest Template pattern /// @@ -122,7 +124,7 @@ protected override void SetContentCore(BinaryContent? content) /// /// protected override PipelineRequestHeaders GetHeadersCore() - => new ClientModelRequestHeaders(Headers); + => new AzureCoreMessageHeaders(Headers); #endregion @@ -180,21 +182,16 @@ protected internal virtual void SetHeader(string name, string value) protected internal abstract IEnumerable EnumerateHeaders(); /// - /// This type adapts the Azure.Core RequestHeaders type to the System.ClientModel - /// PipelineRequestHeaders API. This enables to return - /// a PipelineRequestHeaders type without requiring that - /// inherit from . It calls through to the - /// implementation of Azure.Core RequestHeaders so that this functionality can - /// be maintained. + /// Backwards adapter to MessageHeaders to implement GetHeadersCore /// - private sealed class ClientModelRequestHeaders : PipelineRequestHeaders + private sealed class AzureCoreMessageHeaders : PipelineRequestHeaders { /// /// Headers on the Azure.Core.Request type to adapt to. /// private readonly RequestHeaders _headers; - public ClientModelRequestHeaders(RequestHeaders headers) + public AzureCoreMessageHeaders(RequestHeaders headers) => _headers = headers; public override void Add(string name, string value) diff --git a/sdk/core/Azure.Core/src/RequestFailedException.cs b/sdk/core/Azure.Core/src/RequestFailedException.cs index 2b93d44047f6..0b179002e162 100644 --- a/sdk/core/Azure.Core/src/RequestFailedException.cs +++ b/sdk/core/Azure.Core/src/RequestFailedException.cs @@ -6,9 +6,9 @@ using System.Collections.Generic; using System.ComponentModel; using System.Globalization; -using System.IO; using System.Runtime.Serialization; using System.Text; +using System.Threading.Tasks; using Azure.Core; using Azure.Core.Pipeline; @@ -22,6 +22,19 @@ public class RequestFailedException : ClientResultException, ISerializable { private const string DefaultMessage = "Service request failed."; + /// + /// TBD. + /// + /// + /// + /// + /// + public static async ValueTask CreateAsync(Response response, RequestFailedDetailsParser? parser = default, Exception? innerException = default) + { + ErrorDetails details = await CreateExceptionDetailsAsync(response, parser).ConfigureAwait(false); + return new RequestFailedException(response, details, innerException); + } + /// /// Gets the service specific error code if available. Please refer to the client documentation for the list of supported error codes. /// @@ -52,7 +65,7 @@ public RequestFailedException(Response response, Exception? innerException) /// An inner exception to associate with the new . /// The parser to use to parse the response content. public RequestFailedException(Response response, Exception? innerException, RequestFailedDetailsParser? detailsParser) - : this(response, CreateRequestFailedExceptionContent(response, detailsParser), innerException) + : this(response, CreateExceptionDetails(response, detailsParser), innerException) { } @@ -148,9 +161,22 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont /// public new Response? GetRawResponse() => (Response?)base.GetRawResponse(); - private static ErrorDetails CreateRequestFailedExceptionContent(Response response, RequestFailedDetailsParser? parser) + private static ErrorDetails CreateExceptionDetails(Response response, RequestFailedDetailsParser? parser) + => CreateExceptionDetailsSyncOrAsync(response, parser, async: false).EnsureCompleted(); + + private static async ValueTask CreateExceptionDetailsAsync(Response response, RequestFailedDetailsParser? parser) + => await CreateExceptionDetailsSyncOrAsync(response, parser, async: true).ConfigureAwait(false); + + private static async ValueTask CreateExceptionDetailsSyncOrAsync(Response response, RequestFailedDetailsParser? parser, bool async) { - BufferResponseIfNeeded(response); + if (async) + { + await response.ReadContentAsync().ConfigureAwait(false); + } + else + { + response.ReadContent(); + } parser ??= response.RequestFailedDetailsParser; @@ -202,7 +228,7 @@ private static ErrorDetails CreateRequestFailedExceptionContent(Response respons } } - if (response.ContentStream is MemoryStream && ContentTypeUtilities.TryGetTextEncoding(response.Headers.ContentType, out Encoding _)) + if (ContentTypeUtilities.TryGetTextEncoding(response.Headers.ContentType, out Encoding _)) { messageBuilder .AppendLine() @@ -224,25 +250,6 @@ private static ErrorDetails CreateRequestFailedExceptionContent(Response respons return new ErrorDetails(messageBuilder.ToString(), error?.Code, additionalInfo); } - private static void BufferResponseIfNeeded(Response response) - { - // Buffer into a memory stream if not already buffered - if (response.ContentStream is null or MemoryStream) - { - return; - } - - var bufferedStream = new MemoryStream(); - response.ContentStream.CopyTo(bufferedStream); - - // Dispose the unbuffered stream - response.ContentStream.Dispose(); - - // Reset the position of the buffered stream and set it on the response - bufferedStream.Position = 0; - response.ContentStream = bufferedStream; - } - // This class needs to be internal rather than private so that it can be used // by the System.Text.Json source generator. internal class ErrorResponse diff --git a/sdk/core/Azure.Core/src/Response.cs b/sdk/core/Azure.Core/src/Response.cs index 915394de8939..93500999122d 100644 --- a/sdk/core/Azure.Core/src/Response.cs +++ b/sdk/core/Azure.Core/src/Response.cs @@ -5,9 +5,13 @@ using System.ClientModel.Primitives; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Threading; +using System.Threading.Tasks; using Azure.Core; +using Azure.Core.Buffers; namespace Azure { @@ -18,6 +22,9 @@ namespace Azure public abstract class Response : PipelineResponse #pragma warning restore AZC0012 // Avoid single word type names { + // TODO(matell): The .NET Framework team plans to add BinaryData.Empty in dotnet/runtime#49670, and we can use it then. + private static readonly BinaryData s_EmptyBinaryData = new(Array.Empty()); + /// /// Gets the client request id that was sent to the server as x-ms-client-request-id headers. /// @@ -28,14 +35,6 @@ public abstract class Response : PipelineResponse /// public new virtual ResponseHeaders Headers => new ResponseHeaders(this); - /// - /// Gets the contents of HTTP response, if it is available. - /// - /// - /// Throws when is not a . - /// - public new virtual BinaryData Content => base.Content; - /// /// TBD. /// @@ -48,6 +47,25 @@ protected override PipelineResponseHeaders GetHeadersCore() throw new NotImplementedException(); } + /// + /// Gets the contents of HTTP response, if it is available. + /// + /// + /// Throws when content is not buffered. + /// + public override BinaryData Content + { + get + { + if (ContentStream is null || ContentStream is MemoryStream) + { + return ReadContent(); + } + + throw new InvalidOperationException($"The response is not buffered."); + } + } + internal HttpMessageSanitizer Sanitizer { get; set; } = HttpMessageSanitizer.Default; internal RequestFailedDetailsParser? RequestFailedDetailsParser { get; set; } @@ -124,6 +142,82 @@ internal static void DisposeStreamIfNotBuffered(ref Stream? stream) } } + /// + /// TBD. + /// + /// + /// + /// + public override BinaryData ReadContent(CancellationToken cancellationToken = default) + { + // Derived types should provide an implementation that allows caching + // to improve performance. + if (ContentStream is null) + { + return s_EmptyBinaryData; + } + + if (ContentStream is MemoryStream memoryStream) + { + return memoryStream.TryGetBuffer(out ArraySegment segment) ? + new BinaryData(segment.AsMemory()) : + new BinaryData(memoryStream.ToArray()); + } + + BufferedContentStream bufferStream = new(); + + Stream? contentStream = ContentStream; + contentStream.CopyTo(bufferStream, cancellationToken); + contentStream.Dispose(); + + bufferStream.Position = 0; + ContentStream = bufferStream; + + BinaryData content = BinaryData.FromStream(bufferStream); + bufferStream.Position = 0; + + return content; + } + + /// + /// TBD. + /// + /// + /// + /// + public override async ValueTask ReadContentAsync(CancellationToken cancellationToken = default) + { + // Derived types should provide an implementation that allows caching + // to improve performance. + if (ContentStream is null) + { + return s_EmptyBinaryData; + } + + if (ContentStream is MemoryStream memoryStream) + { + return memoryStream.TryGetBuffer(out ArraySegment segment) ? + new BinaryData(segment.AsMemory()) : + new BinaryData(memoryStream.ToArray()); + } + + BufferedContentStream bufferStream = new(); + + Stream? contentStream = ContentStream; + await contentStream.CopyToAsync(bufferStream, cancellationToken).ConfigureAwait(false); + contentStream.Dispose(); + + bufferStream.Position = 0; + ContentStream = bufferStream; + + BinaryData content = BinaryData.FromStream(bufferStream); + bufferStream.Position = 0; + + return content; + } + + private class BufferedContentStream : MemoryStream { } + #region Private implementation subtypes of abstract Response types private class AzureCoreResponse : Response { @@ -180,6 +274,16 @@ protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(tr { throw new NotSupportedException(DefaultMessage); } + + public override BinaryData ReadContent(CancellationToken cancellationToken = default) + { + throw new NotSupportedException(DefaultMessage); + } + + public override ValueTask ReadContentAsync(CancellationToken cancellationToken = default) + { + throw new NotSupportedException(DefaultMessage); + } } #endregion } diff --git a/sdk/core/Azure.Core/src/RetryOptions.cs b/sdk/core/Azure.Core/src/RetryOptions.cs index f3f84dcac588..d056f884ef06 100644 --- a/sdk/core/Azure.Core/src/RetryOptions.cs +++ b/sdk/core/Azure.Core/src/RetryOptions.cs @@ -20,7 +20,7 @@ public class RetryOptions private TimeSpan _delay = DefaultInitialDelay; private TimeSpan _maxDelay = DefaultMaxDelay; private RetryMode _retryMode = RetryMode.Exponential; - private TimeSpan _networkTimeout = TimeSpan.FromSeconds(100); + private TimeSpan _networkTimeout = ClientOptions.DefaultNetworkTimeout; private bool _frozen; diff --git a/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs b/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs index 73773b9a3fcd..43019e0c5274 100644 --- a/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs +++ b/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs @@ -53,5 +53,25 @@ internal static void ThrowIfCancellationRequested(CancellationToken cancellation ThrowOperationCanceledException(innerException: null, cancellationToken); } } + + /// Throws a cancellation exception if cancellation has been requested via or . + /// The customer provided token. + /// The linked token that is cancelled on timeout provided token. + /// The inner exception to use. + /// The timeout used for the operation. +#pragma warning disable CA1068 // Cancellation token has to be the last parameter + internal static void ThrowIfCancellationRequestedOrTimeout(CancellationToken cancellationToken, CancellationToken timeoutToken, Exception? innerException, TimeSpan timeout) +#pragma warning restore CA1068 + { + ThrowIfCancellationRequested(cancellationToken); + + if (timeoutToken.IsCancellationRequested) + { + throw CreateOperationCanceledException( + innerException, + timeoutToken, + $"The operation was cancelled because it exceeded the configured timeout of {timeout:g}. "); + } + } } -} \ No newline at end of file +} diff --git a/sdk/core/Azure.Core/tests/DisposableHttpPipelineTests.cs b/sdk/core/Azure.Core/tests/DisposableHttpPipelineTests.cs index b81913b71edd..41ce8fd4239d 100644 --- a/sdk/core/Azure.Core/tests/DisposableHttpPipelineTests.cs +++ b/sdk/core/Azure.Core/tests/DisposableHttpPipelineTests.cs @@ -15,7 +15,7 @@ public class DisposableHttpPipelineTests public void DisposeWithDisposableTransport([Values(true, false)] bool isOwned) { var transport = new MockDisposableHttpPipelineTransport(); - var target = new DisposableHttpPipeline(transport, 0, 0, new[] { new MockPolicy(transport, HttpMessageSanitizer.Default) }, ResponseClassifier.Shared, isOwned); + var target = new DisposableHttpPipeline(transport, 0, 0, new[] { new MockPolicy(transport, HttpMessageSanitizer.Default) }, ResponseClassifier.Shared, isOwned, ClientOptions.DefaultNetworkTimeout); target.Dispose(); Assert.AreEqual(isOwned, transport.DisposeCalled); @@ -25,7 +25,7 @@ public void DisposeWithDisposableTransport([Values(true, false)] bool isOwned) public void DisposeWithoutDisposableTransport([Values(true, false)] bool isOwned) { var transport = new MockHttpPipelineTransport(); - var target = new DisposableHttpPipeline(transport, 0, 0, new[] { new MockPolicy(transport, HttpMessageSanitizer.Default) }, ResponseClassifier.Shared, isOwned); + var target = new DisposableHttpPipeline(transport, 0, 0, new[] { new MockPolicy(transport, HttpMessageSanitizer.Default) }, ResponseClassifier.Shared, isOwned, ClientOptions.DefaultNetworkTimeout); target.Dispose(); } diff --git a/sdk/core/Azure.Core/tests/EventSourceTests.cs b/sdk/core/Azure.Core/tests/EventSourceTests.cs index 6f7df6e3a2c9..7e8911b35eb1 100644 --- a/sdk/core/Azure.Core/tests/EventSourceTests.cs +++ b/sdk/core/Azure.Core/tests/EventSourceTests.cs @@ -654,7 +654,12 @@ private async Task SendRequest(bool isSeekable, bool isError, Action + { + await context.Response.Body.WriteAsync(serverBytes, 0, serverBytes.Length).ConfigureAwait(false); + }); + + Response response; + using (HttpMessage message = pipeline.CreateMessage()) + { + message.Request.Uri.Reset(testServer.Address); + message.BufferResponse = buffer; + + await pipeline.SendAsync(message, default).ConfigureAwait(false); + + response = message.ExtractResponse(); + + Assert.IsFalse(message.HasResponse); + } + + Assert.NotNull(response.ContentStream); + + byte[] clientBytes = new byte[serverBytes.Length]; + int readLength = 0; + while (readLength < serverBytes.Length) + { + readLength += await response.ContentStream.ReadAsync(clientBytes, 0, serverBytes.Length); + } + + Assert.AreEqual(serverBytes.Length, readLength); + CollectionAssert.AreEqual(serverBytes, clientBytes); + } + #region Helpers + internal class MockClientOptions : ClientOptions + { + } + private class StatusCodeHandler : ResponseClassificationHandler { private readonly int _statusCode; diff --git a/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs b/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs index 9a8a1e2d25ba..d18d0f4084d1 100644 --- a/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs +++ b/sdk/core/Azure.Core/tests/HttpPipelineFunctionalTests.cs @@ -495,8 +495,8 @@ public void TimeoutsResponseBuffering() message.BufferResponse = true; var exception = Assert.ThrowsAsync(async () => await ExecuteRequest(message, httpPipeline)); - Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.5. " + - "Network timeout can be adjusted in ClientOptions.Retry.NetworkTimeout.", exception.Message); + Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.5. ", + exception.Message); testDoneTcs.Cancel(); } @@ -530,8 +530,8 @@ public void TimeoutsBodyBuffering() message.BufferResponse = true; var exception = Assert.ThrowsAsync(async () => await ExecuteRequest(message, httpPipeline)); - Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.5. " + - "Network timeout can be adjusted in ClientOptions.Retry.NetworkTimeout.", exception.Message); + Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.5. ", + exception.Message); testDoneTcs.Cancel(); } diff --git a/sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs b/sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs deleted file mode 100644 index 26fbc8045210..000000000000 --- a/sdk/core/Azure.Core/tests/ResponseBodyPolicyTests.cs +++ /dev/null @@ -1,402 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; -using Azure.Core.Pipeline; -using Azure.Core.TestFramework; -using NUnit.Framework; -using NUnit.Framework.Internal; - -namespace Azure.Core.Tests -{ - public class ResponseBodyPolicyTests : SyncAsyncPolicyTestBase - { - private static HttpPipelinePolicy NoTimeoutPolicy = new ResponseBodyPolicy(Timeout.InfiniteTimeSpan); - - private static HttpPipelinePolicy TimeoutPolicy = new ResponseBodyPolicy(TimeSpan.FromMilliseconds(50)); - - public ResponseBodyPolicyTests(bool isAsync) : base(isAsync) { } - - [Test] - public async Task ReadsEntireBodyIntoMemoryStream() - { - MockResponse mockResponse = new MockResponse(200); - var readTrackingStream = new ReadTrackingStream(128, int.MaxValue); - mockResponse.ContentStream = readTrackingStream; - - MockTransport mockTransport = CreateMockTransport(mockResponse); - Response response = await SendGetRequest(mockTransport, NoTimeoutPolicy); - - Assert.IsInstanceOf(response.ContentStream); - var ms = (MemoryStream)response.ContentStream; - - Assert.AreEqual(128, ms.Length); - foreach (var b in ms.ToArray()) - { - Assert.AreEqual(ReadTrackingStream.ContentByteValue, b); - } - Assert.AreEqual(128, readTrackingStream.BytesRead); - Assert.AreEqual(0, ms.Position); - } - - [Test] - public void SurfacesStreamReadingExceptions() - { - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = new ReadTrackingStream(128, 64) - }; - - MockTransport mockTransport = CreateMockTransport(mockResponse); - Assert.ThrowsAsync(async () => await SendGetRequest(mockTransport, NoTimeoutPolicy)); - } - - [Test] - public async Task SkipsResponsesWithoutContent() - { - MockResponse mockResponse = new MockResponse(200); - - MockTransport mockTransport = CreateMockTransport(mockResponse); - Response response = await SendGetRequest(mockTransport, NoTimeoutPolicy); - Assert.Null(response.ContentStream); - } - - [Test] - public async Task ClosesStreamAfterCopying() - { - ReadTrackingStream readTrackingStream = new ReadTrackingStream(128, int.MaxValue); - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = readTrackingStream - }; - - MockTransport mockTransport = CreateMockTransport(mockResponse); - await SendGetRequest(mockTransport, NoTimeoutPolicy); - - Assert.True(readTrackingStream.IsClosed); - } - - [Test] - public async Task DoesntBufferWhenDisabled() - { - ReadTrackingStream readTrackingStream = new ReadTrackingStream(128, int.MaxValue); - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = readTrackingStream - }; - - MockTransport mockTransport = CreateMockTransport(mockResponse); - Response response = await SendGetRequest(mockTransport, NoTimeoutPolicy, bufferResponse: false); - - Assert.IsNotInstanceOf(response.ContentStream); - } - - [Test] - public async Task WrapsNonBufferedStreamsWithTimeoutStream() - { - var hangingStream = new HangingReadStream(); - - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = hangingStream - }; - - MockTransport mockTransport = new MockTransport(mockResponse); - Response response = await SendGetRequest(mockTransport, TimeoutPolicy, bufferResponse: false); - - var buffer = new byte[100]; - Assert.ThrowsAsync(async () => await response.ContentStream.ReadAsync(buffer, 0, 100)); - Assert.AreEqual(50, hangingStream.ReadTimeout); - } - - [Test] - public async Task WrapsNonBufferedStreamsWithTimeoutStreamCopyToAsync() - { - var hangingStream = new HangingReadStream(); - - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = hangingStream - }; - - MockTransport mockTransport = new MockTransport(mockResponse); - Response response = await SendGetRequest(mockTransport, TimeoutPolicy, bufferResponse: false); - - var memoryStream = new MemoryStream(); - Assert.ThrowsAsync(async () => await response.ContentStream.CopyToAsync(memoryStream)); - Assert.AreEqual(50, hangingStream.ReadTimeout); - } - - [Test] - public async Task SetsReadTimeoutToProvidedValue() - { - var hangingStream = new HangingReadStream(); - - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = hangingStream - }; - - MockTransport mockTransport = new MockTransport(mockResponse); - Response response = await SendGetRequest(mockTransport, new ResponseBodyPolicy(TimeSpan.FromMilliseconds(1234567)), bufferResponse: false); - - //Assert.IsInstanceOf(response.ContentStream); - Assert.IsFalse(response.ContentStream.CanWrite); - Assert.AreEqual(1234567, hangingStream.ReadTimeout); - } - - [Test] - public async Task BufferingRespectsCancellationToken() - { - var slowReadStream = new SlowReadStream(); - - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = slowReadStream - }; - - MockTransport mockTransport = CreateMockTransport(mockResponse); - CancellationTokenSource cts = new CancellationTokenSource(100); - - Task getRequestTask = Task.Run(async () => await SendGetRequest(mockTransport, NoTimeoutPolicy, bufferResponse: true, cancellationToken: cts.Token)); - - await slowReadStream.StartedReader.Task; - - cts.Cancel(); - - Assert.That(async () => await getRequestTask, Throws.InstanceOf()); - } - - [Test] - public void CanOverrideDefaultNetworkTimeout() - { - var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - - MockTransport mockTransport = MockTransport.FromMessageCallback(message => - { - tcs.Task.Wait(message.CancellationToken); - return null; - }); - - var exception = Assert.ThrowsAsync(async () => await SendRequestAsync(mockTransport, message => - { - message.NetworkTimeout = TimeSpan.FromMilliseconds(30); - }, new ResponseBodyPolicy(TimeSpan.MaxValue), bufferResponse: false)); - Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.03. " + - "Network timeout can be adjusted in ClientOptions.Retry.NetworkTimeout.", exception.Message); - } - - [Test] - public async Task CanOverrideDefaultNetworkTimeout_Stream() - { - var hangingStream = new HangingReadStream(); - - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = hangingStream - }; - - MockTransport mockTransport = new MockTransport(mockResponse); - Response response = await SendRequestAsync(mockTransport, message => - { - message.NetworkTimeout = TimeSpan.FromMilliseconds(30); - }, new ResponseBodyPolicy(TimeSpan.MaxValue), bufferResponse: false); - - //Assert.IsInstanceOf(response.ContentStream); - Assert.IsFalse(response.ContentStream.CanWrite); - Assert.AreEqual(30, hangingStream.ReadTimeout); - } - - private static IEnumerable GetExceptionCases() - { - yield return new object[] { new IOException(), TimeoutPolicy}; - yield return new object[] { new IOException(), NoTimeoutPolicy}; - yield return new object[] { new ObjectDisposedException("test"), TimeoutPolicy}; - yield return new object[] { new ObjectDisposedException("test"), NoTimeoutPolicy}; - yield return new object[] { new OperationCanceledException(), TimeoutPolicy}; - yield return new object[] { new OperationCanceledException(), NoTimeoutPolicy}; - yield return new object[] { new NotSupportedException(), TimeoutPolicy}; - yield return new object[] { new NotSupportedException(), NoTimeoutPolicy}; - } - - [TestCaseSource(nameof(GetExceptionCases))] - public void ExceptionsTranslatedCorrectlyWhenCanceled(Exception exception, HttpPipelinePolicy policy) - { - var cts = new CancellationTokenSource(); - var stream = new CancelingStream(cts, exception); - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = stream - }; - - MockTransport mockTransport = CreateMockTransport(mockResponse); - Assert.ThrowsAsync(async () => await SendGetRequest(mockTransport, policy, cancellationToken: cts.Token)); - Assert.IsTrue(stream.IsClosed); - } - - [TestCaseSource(nameof(GetExceptionCases))] - public void ExceptionsNotTranslatedWhenNotCanceled(Exception exception, HttpPipelinePolicy policy) - { - var cts = new CancellationTokenSource(); - var stream = new CancelingStream(cts, exception, false); - MockResponse mockResponse = new MockResponse(200) - { - ContentStream = stream - }; - - MockTransport mockTransport = CreateMockTransport(mockResponse); - var thrown = Assert.CatchAsync(async () => await SendGetRequest(mockTransport, policy, cancellationToken: cts.Token)); - Assert.AreSame(exception, thrown); - Assert.IsFalse(stream.IsClosed); - } - - private class SlowReadStream : TestReadStream - { - public readonly TaskCompletionSource StartedReader = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - StartedReader.TrySetResult(null); - await Task.Delay(20, cancellationToken); - return 10; - } - - public override int Read(byte[] buffer, int offset, int count) - { - StartedReader.TrySetResult(null); - Thread.Sleep(20); - return 10; - } - } - - private class HangingReadStream : TestReadStream - { - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - await Task.Delay(Timeout.Infinite, cancellationToken); - return 0; - } - - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - - public override int ReadTimeout { get; set; } - - public override bool CanTimeout { get; } = true; - } - - private class ReadTrackingStream : TestReadStream - { - public const int ContentByteValue = 233; - - private readonly int _size; - - private readonly int _throwAfter; - - public ReadTrackingStream(int size, int throwAfter) - { - _size = size; - _throwAfter = throwAfter; - } - - public int BytesRead { get; set; } - - public override int Read(byte[] buffer, int offset, int count) - { - if (BytesRead == _size) - { - return 0; - } - - int left = Math.Min(count, _size); - Span span = buffer.AsSpan(offset, left); - - for (int i = 0; i < span.Length; i++) - { - span[i] = ContentByteValue; - } - - BytesRead += left; - - if (BytesRead > _throwAfter) - { - throw new IOException(); - } - - return left; - } - - public override void Close() - { - IsClosed = true; - base.Close(); - } - - public bool IsClosed { get; set; } - } - - private class CancelingStream : TestReadStream - { - private readonly Exception _exceptionToThrow; - private readonly CancellationTokenSource _cancellationTokenSource; - private readonly bool _cancel; - - public CancelingStream(CancellationTokenSource cancellationTokenSource, Exception exceptionToThrow, bool cancel = true) - { - _exceptionToThrow = exceptionToThrow; - _cancellationTokenSource = cancellationTokenSource; - _cancel = cancel; - } - - public override int Read(byte[] buffer, int offset, int count) - { - if (_cancel) - _cancellationTokenSource.Cancel(); - throw _exceptionToThrow; - } - - public override void Close() - { - IsClosed = true; - base.Close(); - } - - public bool IsClosed { get; set; } - } - - private abstract class TestReadStream: Stream - { - public override bool CanRead { get; } = true; - public override bool CanSeek { get; } - public override bool CanWrite { get; } - public override long Length { get; } - public override long Position { get; set; } - - public override void Flush() - { - throw new System.NotImplementedException(); - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new System.NotImplementedException(); - } - - public override void SetLength(long value) - { - throw new System.NotImplementedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new System.NotImplementedException(); - } - } - } -} diff --git a/sdk/core/Azure.Core/tests/ResponseBufferingTests.cs b/sdk/core/Azure.Core/tests/ResponseBufferingTests.cs new file mode 100644 index 000000000000..b0954f01cb83 --- /dev/null +++ b/sdk/core/Azure.Core/tests/ResponseBufferingTests.cs @@ -0,0 +1,415 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core.Pipeline; +using Azure.Core.TestFramework; +using NUnit.Framework; +using NUnit.Framework.Internal; + +namespace Azure.Core.Tests; + +public class ResponseBufferingTests : SyncAsyncPolicyTestBase +{ + public ResponseBufferingTests(bool isAsync) : base(isAsync) + { + } + + [Test] + public async Task ReadsEntireBodyIntoMemoryStream() + { + MockResponse mockResponse = new MockResponse(200); + var readTrackingStream = new ReadTrackingStream(128, int.MaxValue); + mockResponse.ContentStream = readTrackingStream; + + MockTransport mockTransport = CreateMockTransport(mockResponse); + Response response = await SendGetRequestAsync(mockTransport, Timeout.InfiniteTimeSpan); + + Assert.IsInstanceOf(response.ContentStream); + var ms = (MemoryStream)response.ContentStream; + + Assert.AreEqual(128, ms.Length); + foreach (var b in ms.ToArray()) + { + Assert.AreEqual(ReadTrackingStream.ContentByteValue, b); + } + Assert.AreEqual(128, readTrackingStream.BytesRead); + Assert.AreEqual(0, ms.Position); + } + + [Test] + public void SurfacesStreamReadingExceptions() + { + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = new ReadTrackingStream(128, 64) + }; + + MockTransport mockTransport = CreateMockTransport(mockResponse); + Assert.ThrowsAsync(async () => await SendGetRequestAsync(mockTransport, Timeout.InfiniteTimeSpan)); + } + + [Test] + public async Task SkipsResponsesWithoutContent() + { + MockResponse mockResponse = new MockResponse(200); + + MockTransport mockTransport = CreateMockTransport(mockResponse); + Response response = await SendGetRequestAsync(mockTransport, Timeout.InfiniteTimeSpan); + Assert.Null(response.ContentStream); + } + + [Test] + public async Task ClosesStreamAfterCopying() + { + ReadTrackingStream readTrackingStream = new ReadTrackingStream(128, int.MaxValue); + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = readTrackingStream + }; + + MockTransport mockTransport = CreateMockTransport(mockResponse); + await SendGetRequestAsync(mockTransport, Timeout.InfiniteTimeSpan); + + Assert.True(readTrackingStream.IsClosed); + } + + [Test] + public async Task DoesntBufferWhenDisabled() + { + ReadTrackingStream readTrackingStream = new ReadTrackingStream(128, int.MaxValue); + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = readTrackingStream + }; + + MockTransport mockTransport = CreateMockTransport(mockResponse); + Response response = await SendGetRequestAsync(mockTransport, Timeout.InfiniteTimeSpan, bufferResponse: false); + + Assert.IsNotInstanceOf(response.ContentStream); + } + + [Test] + public async Task WrapsNonBufferedStreamsWithTimeoutStream() + { + var hangingStream = new HangingReadStream(); + + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = hangingStream + }; + + MockTransport mockTransport = new MockTransport(mockResponse); + Response response = await SendGetRequestAsync(mockTransport, TimeSpan.FromMilliseconds(50), bufferResponse: false); + + var buffer = new byte[100]; + Assert.ThrowsAsync(async () => await response.ContentStream.ReadAsync(buffer, 0, 100)); + Assert.AreEqual(50, hangingStream.ReadTimeout); + } + + [Test] + public async Task WrapsNonBufferedStreamsWithTimeoutStreamCopyToAsync() + { + var hangingStream = new HangingReadStream(); + + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = hangingStream + }; + + MockTransport mockTransport = new MockTransport(mockResponse); + Response response = await SendGetRequestAsync(mockTransport, TimeSpan.FromMilliseconds(50), bufferResponse: false); + + var memoryStream = new MemoryStream(); + Assert.ThrowsAsync(async () => await response.ContentStream.CopyToAsync(memoryStream)); + Assert.AreEqual(50, hangingStream.ReadTimeout); + } + + [Test] + public async Task SetsReadTimeoutToProvidedValue() + { + var hangingStream = new HangingReadStream(); + + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = hangingStream + }; + + MockTransport mockTransport = new MockTransport(mockResponse); + Response response = await SendGetRequestAsync(mockTransport, TimeSpan.FromMilliseconds(1234567), bufferResponse: false); + + //Assert.IsInstanceOf(response.ContentStream); + Assert.IsFalse(response.ContentStream.CanWrite); + Assert.AreEqual(1234567, hangingStream.ReadTimeout); + } + + [Test] + public async Task BufferingRespectsCancellationToken() + { + var slowReadStream = new SlowReadStream(); + + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = slowReadStream + }; + + MockTransport mockTransport = CreateMockTransport(mockResponse); + CancellationTokenSource cts = new CancellationTokenSource(100); + + Task getRequestTask = Task.Run(async () => await SendGetRequestAsync(mockTransport, Timeout.InfiniteTimeSpan, bufferResponse: true, cancellationToken: cts.Token)); + + await slowReadStream.StartedReader.Task; + + cts.Cancel(); + + Assert.That(async () => await getRequestTask, Throws.InstanceOf()); + } + + [Test] + public void CanOverrideDefaultNetworkTimeout() + { + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + MockTransport mockTransport = MockTransport.FromMessageCallback(message => + { + tcs.Task.Wait(message.CancellationToken); + return null; + }); + + var exception = Assert.ThrowsAsync(async () => await SendGetRequestAsync(mockTransport, TimeSpan.FromMilliseconds(30), bufferResponse: false)); + Assert.AreEqual("The operation was cancelled because it exceeded the configured timeout of 0:00:00.03. ", + exception.Message); + } + + private static IEnumerable GetExceptionCases() + { + yield return new object[] { new IOException(), TimeSpan.FromMilliseconds(50) }; + yield return new object[] { new IOException(), Timeout.InfiniteTimeSpan }; + yield return new object[] { new ObjectDisposedException("test"), TimeSpan.FromMilliseconds(50) }; + yield return new object[] { new ObjectDisposedException("test"), Timeout.InfiniteTimeSpan }; + yield return new object[] { new OperationCanceledException(), TimeSpan.FromMilliseconds(50) }; + yield return new object[] { new OperationCanceledException(), Timeout.InfiniteTimeSpan }; + yield return new object[] { new NotSupportedException(), TimeSpan.FromMilliseconds(50) }; + yield return new object[] { new NotSupportedException(), Timeout.InfiniteTimeSpan }; + } + + [TestCaseSource(nameof(GetExceptionCases))] + public void ExceptionsTranslatedCorrectlyWhenCanceled(Exception exception, TimeSpan timeout) + { + var cts = new CancellationTokenSource(); + var stream = new CancelingStream(cts, exception); + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = stream + }; + + MockTransport mockTransport = CreateMockTransport(mockResponse); + Assert.ThrowsAsync(async () => await SendGetRequestAsync(mockTransport, timeout, cancellationToken: cts.Token)); + Assert.IsTrue(stream.IsClosed); + } + + [TestCaseSource(nameof(GetExceptionCases))] + public void ExceptionsNotTranslatedWhenNotCanceled(Exception exception, TimeSpan timeout) + { + var cts = new CancellationTokenSource(); + var stream = new CancelingStream(cts, exception, false); + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = stream + }; + + MockTransport mockTransport = CreateMockTransport(mockResponse); + var thrown = Assert.CatchAsync(async () => await SendGetRequestAsync(mockTransport, timeout, cancellationToken: cts.Token)); + Assert.AreSame(exception, thrown); + Assert.IsFalse(stream.IsClosed); + } + + [Test] + public async Task CanOverrideDefaultNetworkTimeout_Stream() + { + var hangingStream = new HangingReadStream(); + + MockResponse mockResponse = new MockResponse(200) + { + ContentStream = hangingStream + }; + + MockTransport mockTransport = new MockTransport(mockResponse); + Response response = await SendGetRequestAsync(mockTransport, TimeSpan.FromMilliseconds(30), bufferResponse: false); + + //Assert.IsInstanceOf(response.ContentStream); + Assert.IsFalse(response.ContentStream.CanWrite); + Assert.AreEqual(30, hangingStream.ReadTimeout); + } + + #region Helpers + + protected async Task SendGetRequestAsync(HttpPipelineTransport transport, TimeSpan networkTimeout, bool bufferResponse = true, CancellationToken cancellationToken = default) + { + HttpPipeline pipeline = new(transport); + HttpMessage message = pipeline.CreateMessage(); + message.NetworkTimeout = networkTimeout; + message.BufferResponse = bufferResponse; + + if (IsAsync) + { + await pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false); + } + else + { + pipeline.Send(message, cancellationToken); + } + + return message.Response; + } + + private class SlowReadStream : TestReadStream + { + public readonly TaskCompletionSource StartedReader = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + StartedReader.TrySetResult(null); + await Task.Delay(20, cancellationToken); + return 10; + } + + public override int Read(byte[] buffer, int offset, int count) + { + StartedReader.TrySetResult(null); + Thread.Sleep(20); + return 10; + } + } + + private class HangingReadStream : TestReadStream + { + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + await Task.Delay(Timeout.Infinite, cancellationToken); + return 0; + } + + public override int Read(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + + public override int ReadTimeout { get; set; } + + public override bool CanTimeout { get; } = true; + } + + private class ReadTrackingStream : TestReadStream + { + public const int ContentByteValue = 233; + + private readonly int _size; + + private readonly int _throwAfter; + + public ReadTrackingStream(int size, int throwAfter) + { + _size = size; + _throwAfter = throwAfter; + } + + public int BytesRead { get; set; } + + public override int Read(byte[] buffer, int offset, int count) + { + if (BytesRead == _size) + { + return 0; + } + + int left = Math.Min(count, _size); + Span span = buffer.AsSpan(offset, left); + + for (int i = 0; i < span.Length; i++) + { + span[i] = ContentByteValue; + } + + BytesRead += left; + + if (BytesRead > _throwAfter) + { + throw new IOException(); + } + + return left; + } + + public override void Close() + { + IsClosed = true; + base.Close(); + } + + public bool IsClosed { get; set; } + } + + private class CancelingStream : TestReadStream + { + private readonly Exception _exceptionToThrow; + private readonly CancellationTokenSource _cancellationTokenSource; + private readonly bool _cancel; + + public CancelingStream(CancellationTokenSource cancellationTokenSource, Exception exceptionToThrow, bool cancel = true) + { + _exceptionToThrow = exceptionToThrow; + _cancellationTokenSource = cancellationTokenSource; + _cancel = cancel; + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (_cancel) + _cancellationTokenSource.Cancel(); + throw _exceptionToThrow; + } + + public override void Close() + { + IsClosed = true; + base.Close(); + } + + public bool IsClosed { get; set; } + } + + private abstract class TestReadStream : Stream + { + public override bool CanRead { get; } = true; + public override bool CanSeek { get; } + public override bool CanWrite { get; } + public override long Length { get; } + public override long Position { get; set; } + + public override void Flush() + { + throw new System.NotImplementedException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new System.NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new System.NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new System.NotImplementedException(); + } + } + + #endregion +} diff --git a/sdk/core/Azure.Core/tests/RetriableStreamTests.cs b/sdk/core/Azure.Core/tests/RetriableStreamTests.cs index 4e8e1721641f..386e5a956bb8 100644 --- a/sdk/core/Azure.Core/tests/RetriableStreamTests.cs +++ b/sdk/core/Azure.Core/tests/RetriableStreamTests.cs @@ -370,27 +370,42 @@ private Task ReadAsync(Stream stream, byte[] buffer, int offset, int length private static Stream SendTestRequest(HttpPipeline pipeline, long offset) { - using Request request = CreateRequest(pipeline, offset); + using HttpMessage message = CreateMessage(pipeline, offset); - Response response = pipeline.SendRequest(request, CancellationToken.None); - return response.ContentStream; + pipeline.Send(message, CancellationToken.None); + Response response = message.Response; + Stream stream = message.ExtractResponseContent(); + + return stream; } private static async ValueTask SendTestRequestAsync(HttpPipeline pipeline, long offset) { - using Request request = CreateRequest(pipeline, offset); + using HttpMessage message = CreateMessage(pipeline, offset); + + await pipeline.SendAsync(message, CancellationToken.None); + Response response = message.Response; + Stream stream = message.ExtractResponseContent(); - Response response = await pipeline.SendRequestAsync(request, CancellationToken.None); - return response.ContentStream; + return stream; } - private static Request CreateRequest(HttpPipeline pipeline, long offset) + private static HttpMessage CreateMessage(HttpPipeline pipeline, long offset) { Request request = pipeline.CreateRequest(); request.Method = RequestMethod.Get; request.Uri.Reset(new Uri("https://example.com")); request.Headers.Add("Range", "bytes=" + offset); - return request; + HttpMessage message = new(request, ResponseClassifier.Shared); + + // RetriableStream is only used in clients where streaming APIs + // return the network stream to the end-user. RetriableStream lets + // us do this in a way that if a request fails, it can be retried + // according to the retry logic configured for the client's pipeline. + // As such, when it is used clients must set message.BufferResponse + // to false, so we do this in the validation tests as well. + message.BufferResponse = false; + return message; } private class NoLengthStream : ReadOnlyStream diff --git a/sdk/core/Azure.Core/tests/TransportFunctionalTests.cs b/sdk/core/Azure.Core/tests/TransportFunctionalTests.cs index 6411ae3ba22e..2eda351fd96e 100644 --- a/sdk/core/Azure.Core/tests/TransportFunctionalTests.cs +++ b/sdk/core/Azure.Core/tests/TransportFunctionalTests.cs @@ -987,7 +987,14 @@ public async Task StreamReadingExceptionsAreIOExceptions() var transport = GetTransport(); Request request = transport.CreateRequest(); request.Uri.Reset(testServer.Address); - Response response = await ExecuteRequest(request, transport); + HttpMessage messsage = new(request, ResponseClassifier.Shared); + + // This test is explicitly testing the behavior of a response that + // holds a live network stream, so we set BufferResponse to false. + messsage.BufferResponse = false; + + await ProcessAsync(messsage, transport); + Response response = messsage.Response; tcs.SetResult(null); diff --git a/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs b/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs index 82685f517619..2fd7f3c206ac 100644 --- a/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs +++ b/sdk/core/System.ClientModel/src/Convenience/ClientResultOfT.cs @@ -14,7 +14,7 @@ protected internal ClientResult(T value, PipelineResponse response) } /// - /// TBD. Needed for inheritdoc. + /// TBD. Needed for inheritdoc. /// public virtual T Value { get; } } diff --git a/sdk/core/System.ClientModel/tests/ModelReaderWriter/ModelReaderWriterTests.cs b/sdk/core/System.ClientModel/tests/ModelReaderWriter/ModelReaderWriterTests.cs index e63ba4e275f3..e66412cfd987 100644 --- a/sdk/core/System.ClientModel/tests/ModelReaderWriter/ModelReaderWriterTests.cs +++ b/sdk/core/System.ClientModel/tests/ModelReaderWriter/ModelReaderWriterTests.cs @@ -68,20 +68,15 @@ public void ValidateJsonExceptionBinaryData(BinaryData data) [TestCaseSource(typeof(ReaderWriterTestSource), "NullBinaryData")] public void ValidateNullBinaryData(BinaryData data) { - Assert.IsNull(ModelReaderWriter.Read(data)); - Assert.IsNull(ModelReaderWriter.Read(data, typeof(ModelX))); + Assert.Throws(() => ModelReaderWriter.Read(data)); + Assert.Throws(() => ModelReaderWriter.Read(data, typeof(ModelX))); } [TestCaseSource(typeof(ReaderWriterTestSource), "EmptyObjectBinaryData")] public void ValidateEmptyObjectBinaryData(BinaryData data) { - ModelX? x = ModelReaderWriter.Read(data); - Assert.IsNotNull(x); - Assert.IsNull(x!.Kind); - - object? obj = ModelReaderWriter.Read(data, typeof(ModelX)); - Assert.IsNotNull(obj); - Assert.IsNull(((ModelX)obj!).Kind); + Assert.Throws(() => ModelReaderWriter.Read(data)); + Assert.Throws(() => ModelReaderWriter.Read(data, typeof(ModelX))); } [Test] diff --git a/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTests.cs b/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTests.cs index 3a8fadf8572e..7f6941b2cbb0 100644 --- a/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTests.cs +++ b/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTests.cs @@ -34,11 +34,11 @@ protected override void VerifyModel(AvailabilitySetData model, string format) { Dictionary expectedTags = new Dictionary() { { "key", "value" } }; - Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS-3375", model.Id.ToString()); + Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS-3375", model.Id!.ToString()); CollectionAssert.AreEquivalent(expectedTags, model.Tags); Assert.AreEqual("eastus", model.Location); Assert.AreEqual("testAS-3375", model.Name); - Assert.AreEqual("Microsoft.Compute/availabilitySets", model.ResourceType.ToString()); + Assert.AreEqual("Microsoft.Compute/availabilitySets", model.ResourceType!.ToString()); Assert.AreEqual(5, model.PlatformUpdateDomainCount); Assert.AreEqual(3, model.PlatformFaultDomainCount); Assert.AreEqual("Classic", model.Sku.Name); diff --git a/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTestsWithVMs.cs b/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTestsWithVMs.cs index bcd67e33d511..107604113d94 100644 --- a/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTestsWithVMs.cs +++ b/sdk/core/System.ClientModel/tests/ModelReaderWriter/Models/AvailabilitySetDataTestsWithVMs.cs @@ -35,17 +35,17 @@ protected override void VerifyModel(AvailabilitySetData model, string format) { Dictionary expectedTags = new Dictionary() { { "key", "value" } }; - Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS-3375", model.Id.ToString()); + Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS-3375", model.Id!.ToString()); CollectionAssert.AreEquivalent(expectedTags, model.Tags); Assert.AreEqual("eastus", model.Location); Assert.AreEqual("testAS-3375", model.Name); - Assert.AreEqual("Microsoft.Compute/availabilitySets", model.ResourceType.ToString()); + Assert.AreEqual("Microsoft.Compute/availabilitySets", model.ResourceType!.ToString()); Assert.AreEqual(5, model.PlatformUpdateDomainCount); Assert.AreEqual(3, model.PlatformFaultDomainCount); Assert.AreEqual("Classic", model.Sku.Name); Assert.AreEqual(2, model.VirtualMachines.Count); - Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS1", model.VirtualMachines[0].Id.ToString()); - Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS2", model.VirtualMachines[1].Id.ToString()); + Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS1", model.VirtualMachines[0].Id!); + Assert.AreEqual("/subscriptions/e37510d7-33b6-4676-886f-ee75bcc01871/resourceGroups/testRG-6497/providers/Microsoft.Compute/availabilitySets/testAS2", model.VirtualMachines[1].Id!); } protected override void CompareModels(AvailabilitySetData model, AvailabilitySetData model2, string format) diff --git a/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterExtensions.cs b/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterExtensions.cs index b4ad891ec481..816a1a6fb1bd 100644 --- a/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterExtensions.cs +++ b/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterExtensions.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable enable - using System; using System.ClientModel.Primitives; using System.Collections.Generic; @@ -178,7 +176,7 @@ public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset v writer.WriteNumberValue(value.ToUnixTimeSeconds()); } - public static void WriteObjectValue(this Utf8JsonWriter writer, object value) + public static void WriteObjectValue(this Utf8JsonWriter writer, object? value) { switch (value) { diff --git a/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterHelper.cs b/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterHelper.cs index 01aec41339bd..993399273882 100644 --- a/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterHelper.cs +++ b/sdk/core/System.ClientModel/tests/client/ClientShared/ModelReaderWriterHelper.cs @@ -21,8 +21,9 @@ public static void ValidateFormat(IPersistableModel model, string format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateFormat(IPersistableModel model, string format) => ValidateFormat(model, format); + public static void ValidateFormat(IPersistableModel model, string format) + => ValidateFormat(model, format); - private static ModelReaderWriterOptions _wireOptions; + private static ModelReaderWriterOptions? _wireOptions; public static ModelReaderWriterOptions WireOptions => _wireOptions ??= new ModelReaderWriterOptions("W"); } diff --git a/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalDictionary.cs b/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalDictionary.cs index c79c187c4210..2ed656e9a1cb 100644 --- a/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalDictionary.cs +++ b/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalDictionary.cs @@ -5,8 +5,6 @@ using System.Collections; using System.Collections.Generic; -#nullable enable - namespace ClientModel.Tests.ClientShared; internal class OptionalDictionary : IDictionary, IReadOnlyDictionary where TKey : notnull @@ -25,14 +23,14 @@ public OptionalDictionary(OptionalProperty> optionalDi { } - private OptionalDictionary(IDictionary dictionary) + private OptionalDictionary(IDictionary? dictionary) { if (dictionary == null) return; _innerDictionary = new Dictionary(dictionary); } - private OptionalDictionary(IReadOnlyDictionary dictionary) + private OptionalDictionary(IReadOnlyDictionary? dictionary) { if (dictionary == null) return; diff --git a/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalList.cs b/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalList.cs index 0460b0cebc49..d34d05d7fef8 100644 --- a/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalList.cs +++ b/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalList.cs @@ -6,8 +6,6 @@ using System.Collections.Generic; using System.Linq; -#nullable enable - namespace ClientModel.Tests.ClientShared; internal class OptionalList : IList, IReadOnlyList @@ -26,7 +24,7 @@ public OptionalList(OptionalProperty> optionalList) : this(opti { } - private OptionalList(IEnumerable innerList) + private OptionalList(IEnumerable? innerList) { if (innerList == null) { @@ -36,7 +34,7 @@ private OptionalList(IEnumerable innerList) _innerList = innerList.ToList(); } - private OptionalList(IList innerList) + private OptionalList(IList? innerList) { if (innerList == null) { diff --git a/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalProperty.cs b/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalProperty.cs index d86de7e9627e..45b0200e3dc6 100644 --- a/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalProperty.cs +++ b/sdk/core/System.ClientModel/tests/client/ClientShared/OptionalProperty.cs @@ -14,12 +14,17 @@ public static bool IsCollectionDefined(IEnumerable collection) } public static bool IsCollectionDefined(IReadOnlyDictionary collection) + where TKey : notnull { return !(collection is OptionalDictionary changeTrackingList && changeTrackingList.IsUndefined); } - public static bool IsCollectionDefined(IDictionary collection) + public static bool IsCollectionDefined(IDictionary? collection) + where TKey : notnull { + if (collection is null) + return false; + return !(collection is OptionalDictionary changeTrackingList && changeTrackingList.IsUndefined); } @@ -31,7 +36,7 @@ public static bool IsDefined(object value) { return value != null; } - public static bool IsDefined(string value) + public static bool IsDefined(string? value) { return value != null; } @@ -42,27 +47,30 @@ public static bool IsDefined(JsonElement value) } public static IReadOnlyDictionary ToDictionary(OptionalProperty> optional) + where TKey : notnull { if (optional.HasValue) { - return optional.Value; + return optional.Value!; } return new OptionalDictionary(optional); } public static IDictionary ToDictionary(OptionalProperty> optional) + where TKey : notnull { if (optional.HasValue) { - return optional.Value; + return optional.Value!; } return new OptionalDictionary(optional); } + public static IReadOnlyList ToList(OptionalProperty> optional) { if (optional.HasValue) { - return optional.Value; + return optional.Value!; } return new OptionalList(optional); } @@ -71,7 +79,7 @@ public static IList ToList(OptionalProperty> optional) { if (optional.HasValue) { - return optional.Value; + return optional.Value!; } return new OptionalList(optional); } @@ -93,15 +101,15 @@ public static IList ToList(OptionalProperty> optional) public readonly struct OptionalProperty { - public OptionalProperty(T value) : this() + public OptionalProperty(T? value) : this() { Value = value; - HasValue = true; + HasValue = value is not null; } - public T Value { get; } + public T? Value { get; } public bool HasValue { get; } - public static implicit operator OptionalProperty(T value) => new OptionalProperty(value); - public static implicit operator T(OptionalProperty optional) => optional.Value; + public static implicit operator OptionalProperty(T? value) => new OptionalProperty(value); + public static implicit operator T?(OptionalProperty optional) => optional.Value; } diff --git a/sdk/core/System.ClientModel/tests/client/ClientShared/TypeFormatters.cs b/sdk/core/System.ClientModel/tests/client/ClientShared/TypeFormatters.cs index 863ec55193d3..284351df306d 100644 --- a/sdk/core/System.ClientModel/tests/client/ClientShared/TypeFormatters.cs +++ b/sdk/core/System.ClientModel/tests/client/ClientShared/TypeFormatters.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable enable - using System; using System.Collections.Generic; using System.Globalization; @@ -155,4 +153,4 @@ public static string ConvertToString(object? value, string? format = null) BinaryData binaryData => TypeFormatters.ConvertToString(binaryData.ToArray(), format), _ => value.ToString()! }; -} \ No newline at end of file +} diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/BaseModel.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/BaseModel.cs index fb50d2ac81b1..b002cede82ad 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/BaseModel.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/BaseModel.cs @@ -13,7 +13,7 @@ public abstract class BaseModel : IJsonModel { private Dictionary _rawData; - public static implicit operator BinaryContent(BaseModel baseModel) + public static implicit operator BinaryContent?(BaseModel? baseModel) { if (baseModel == null) { @@ -31,13 +31,13 @@ public static explicit operator BaseModel(ClientResult result) return DeserializeBaseModel(jsonDocument.RootElement, ModelReaderWriterHelper.WireOptions); } - protected internal BaseModel(Dictionary rawData) + protected internal BaseModel(Dictionary? rawData) { _rawData = rawData ?? new Dictionary(); } - public string Kind { get; internal set; } - public string Name { get; set; } + public string? Kind { get; internal set; } + public string? Name { get; set; } protected internal void SerializeRawData(Utf8JsonWriter writer) { @@ -77,16 +77,16 @@ private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) writer.WriteEndObject(); } - internal static BaseModel DeserializeBaseModel(BinaryData data, ModelReaderWriterOptions options) + internal static BaseModel DeserializeBaseModel(BinaryData data, ModelReaderWriterOptions? options) => DeserializeBaseModel(JsonDocument.Parse(data.ToString()).RootElement, options); - internal static BaseModel DeserializeBaseModel(JsonElement element, ModelReaderWriterOptions options = default) + internal static BaseModel DeserializeBaseModel(JsonElement element, ModelReaderWriterOptions? options = default) { options ??= ModelReaderWriterHelper.WireOptions; if (element.ValueKind == JsonValueKind.Null) { - return null; + throw new JsonException($"Invalid JSON provided to deserialize type '{nameof(BaseModel)}'"); } if (element.TryGetProperty("kind", out JsonElement discriminator)) { @@ -99,10 +99,11 @@ internal static BaseModel DeserializeBaseModel(JsonElement element, ModelReaderW } } - //Deserialize unknown subtype - string kind = default; + // Deserialize unknown subtype + string? kind = default; OptionalProperty name = default; Dictionary rawData = new Dictionary(); + foreach (var property in element.EnumerateObject()) { if (property.NameEquals("kind"u8)) @@ -121,6 +122,7 @@ internal static BaseModel DeserializeBaseModel(JsonElement element, ModelReaderW rawData.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); } } + return new UnknownBaseModel(kind, name, rawData); } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelX.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelX.cs index b381b2bbaf60..bd0b8660387b 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelX.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelX.cs @@ -11,13 +11,14 @@ namespace System.ClientModel.Tests.Client.ModelReaderWriterTests.Models { public class ModelX : BaseModel, IJsonModel { - public ModelX() - : base(null) + public ModelX() : base(null) { Kind = "X"; + Fields = new List(); + KeyValuePairs = new Dictionary(); } - internal ModelX(string kind, string name, int xProperty, int? nullProperty, IList fields, IDictionary keyValuePairs, Dictionary rawData) + internal ModelX(string kind, string? name, int xProperty, int? nullProperty, IList fields, IDictionary keyValuePairs, Dictionary rawData) : base(rawData) { Kind = kind; @@ -33,7 +34,7 @@ internal ModelX(string kind, string name, int xProperty, int? nullProperty, ILis public int? NullProperty = null; public IDictionary KeyValuePairs { get; } - public static implicit operator BinaryContent(ModelX modelX) + public static implicit operator BinaryContent?(ModelX? modelX) { if (modelX == null) { @@ -81,7 +82,7 @@ private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) if (OptionalProperty.IsDefined(NullProperty)) { writer.WritePropertyName("nullProperty"u8); - writer.WriteNumberValue(NullProperty.Value); + writer.WriteNumberValue(NullProperty!.Value); } if (OptionalProperty.IsCollectionDefined(KeyValuePairs)) { @@ -112,15 +113,16 @@ private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) writer.WriteEndObject(); } - internal static ModelX DeserializeModelX(JsonElement element, ModelReaderWriterOptions options = default) + internal static ModelX DeserializeModelX(JsonElement element, ModelReaderWriterOptions? options = default) { options ??= ModelReaderWriterHelper.WireOptions; if (element.ValueKind == JsonValueKind.Null) { - return null; + throw new JsonException($"Invalid JSON provided to deserialize type '{nameof(ModelX)}'"); } - string kind = default; + + string? kind = default; OptionalProperty name = default; int xProperty = default; OptionalProperty nullProperty = default; @@ -142,7 +144,7 @@ internal static ModelX DeserializeModelX(JsonElement element, ModelReaderWriterO } if (property.NameEquals("fields"u8)) { - fields = property.Value.EnumerateArray().Select(element => element.GetString()).ToList(); + fields = property.Value.EnumerateArray().Select(element => element.GetString()!).ToList(); continue; } if (property.NameEquals("nullProperty"u8)) @@ -159,7 +161,7 @@ internal static ModelX DeserializeModelX(JsonElement element, ModelReaderWriterO Dictionary dictionary = new Dictionary(); foreach (var property0 in property.Value.EnumerateObject()) { - dictionary.Add(property0.Name, property0.Value.GetString()); + dictionary.Add(property0.Name, property0.Value.GetString()!); } keyValuePairs = dictionary; continue; @@ -175,13 +177,18 @@ internal static ModelX DeserializeModelX(JsonElement element, ModelReaderWriterO rawData.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); } } + + if (kind is null) + { + throw new JsonException($"Invalid JSON provided to deserialize type '{nameof(ModelX)}': Missing 'kind' property."); + } + return new ModelX(kind, name, xProperty, OptionalProperty.ToNullable(nullProperty), OptionalProperty.ToList(fields), OptionalProperty.ToDictionary(keyValuePairs), rawData); } ModelX IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) { ModelReaderWriterHelper.ValidateFormat(this, options.Format); - return DeserializeModelX(JsonDocument.Parse(data.ToString()).RootElement, options); } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelY.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelY.cs index ac42c88881ba..436ff68d6260 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelY.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/ModelY.cs @@ -16,7 +16,7 @@ public ModelY() Kind = "Y"; } - internal ModelY(string kind, string name, string yProperty, Dictionary rawData) + internal ModelY(string kind, string? name, string? yProperty, Dictionary rawData) : base(rawData) { Kind = kind; @@ -24,12 +24,14 @@ internal ModelY(string kind, string name, string yProperty, Dictionary.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => Serialize(writer, options); + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions? options) => Serialize(writer, options); - private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) + private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions? options) { + options ??= ModelReaderWriterOptions.Json; + writer.WriteStartObject(); writer.WritePropertyName("kind"u8); writer.WriteStringValue(Kind); @@ -50,18 +52,19 @@ private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) writer.WriteEndObject(); } - internal static ModelY DeserializeModelY(JsonElement element, ModelReaderWriterOptions options = default) + internal static ModelY DeserializeModelY(JsonElement element, ModelReaderWriterOptions? options = default) { options ??= ModelReaderWriterHelper.WireOptions; if (element.ValueKind == JsonValueKind.Null) { - return null; + throw new JsonException($"Invalid JSON provided to deserialize type '{nameof(ModelY)}'"); } - string kind = default; + string? kind = default; OptionalProperty name = default; OptionalProperty yProperty = default; Dictionary rawData = new Dictionary(); + foreach (var property in element.EnumerateObject()) { if (property.NameEquals("kind"u8)) @@ -85,6 +88,12 @@ internal static ModelY DeserializeModelY(JsonElement element, ModelReaderWriterO rawData.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); } } + + if (kind is null) + { + throw new JsonException($"Invalid JSON provided to deserialize type '{nameof(ModelY)}': Missing 'kind' property"); + } + return new ModelY(kind, name, yProperty, rawData); } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/UnknownBaseModel.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/UnknownBaseModel.cs index 492b073c665f..e58927509839 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/UnknownBaseModel.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/DiscriminatorSet/UnknownBaseModel.cs @@ -16,7 +16,7 @@ public UnknownBaseModel() Kind = "Unknown"; } - internal UnknownBaseModel(string kind, string name, Dictionary rawData) + internal UnknownBaseModel(string? kind, string? name, Dictionary rawData) : base(rawData) { Kind = kind; @@ -47,7 +47,7 @@ private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) writer.WriteEndObject(); } - internal static BaseModel DeserializeUnknownBaseModel(JsonElement element, ModelReaderWriterOptions options = default) => DeserializeBaseModel(element, options); + internal static BaseModel DeserializeUnknownBaseModel(JsonElement element, ModelReaderWriterOptions? options = default) => DeserializeBaseModel(element, options); BaseModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) { diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelAsStruct.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelAsStruct.cs index 6e557d3acf20..937c0747f6f4 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelAsStruct.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelAsStruct.cs @@ -71,7 +71,7 @@ ModelAsStruct IPersistableModel.Create(BinaryData data, ModelRead return DeserializeInputAdditionalPropertiesModelStruct(doc.RootElement, options); } - internal static ModelAsStruct DeserializeInputAdditionalPropertiesModelStruct(JsonElement element, ModelReaderWriterOptions options = default) + internal static ModelAsStruct DeserializeInputAdditionalPropertiesModelStruct(JsonElement element, ModelReaderWriterOptions? options = default) { options ??= ModelReaderWriterHelper.WireOptions; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelWithPersistableOnly.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelWithPersistableOnly.cs index 3c02b640d74f..87855a35865f 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelWithPersistableOnly.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/Models/ModelWithPersistableOnly.cs @@ -12,13 +12,16 @@ namespace System.ClientModel.Tests.Client.ModelReaderWriterTests.Models { public class ModelWithPersistableOnly : IPersistableModel { - private Dictionary _rawData; + private readonly Dictionary _rawData; public ModelWithPersistableOnly() { + _rawData = new Dictionary(); + Fields = new List(); + KeyValuePairs = new Dictionary(); } - internal ModelWithPersistableOnly(string name, int xProperty, int? nullProperty, IList fields, IDictionary keyValuePairs, Dictionary rawData) + internal ModelWithPersistableOnly(string? name, int xProperty, int? nullProperty, IList fields, IDictionary keyValuePairs, Dictionary rawData) { Name = name; XProperty = xProperty; @@ -28,8 +31,25 @@ internal ModelWithPersistableOnly(string name, int xProperty, int? nullProperty, _rawData = rawData; } - public string Name { get; } - public int XProperty { get; } + private void AssertHasValue(T? value, string name) + { + if (value is null) + throw new ArgumentNullException(name); + } + + public string? Name { get; } + + private int? _xProperty; + public int XProperty + { + get + { + AssertHasValue(_xProperty, nameof(XProperty)); + return _xProperty!.Value; + } + set => _xProperty = value; + } + public IList Fields { get; } public int? NullProperty = null; public IDictionary KeyValuePairs { get; } @@ -55,7 +75,7 @@ private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) if (OptionalProperty.IsDefined(NullProperty)) { writer.WritePropertyName("nullProperty"u8); - writer.WriteNumberValue(NullProperty.Value); + writer.WriteNumberValue(NullProperty!.Value); } if (OptionalProperty.IsCollectionDefined(KeyValuePairs)) { @@ -100,14 +120,15 @@ private void SerializeRawData(Utf8JsonWriter writer) } } - internal static ModelWithPersistableOnly DeserializeModelX(JsonElement element, ModelReaderWriterOptions options = default) + internal static ModelWithPersistableOnly DeserializeModelX(JsonElement element, ModelReaderWriterOptions? options = default) { options ??= ModelReaderWriterHelper.WireOptions; if (element.ValueKind == JsonValueKind.Null) { - return null; + throw new JsonException($"Invalid JSON provided to deserialize type '{nameof(ModelWithPersistableOnly)}'"); } + OptionalProperty name = default; int xProperty = default; OptionalProperty nullProperty = default; @@ -115,7 +136,7 @@ internal static ModelWithPersistableOnly DeserializeModelX(JsonElement element, OptionalProperty> keyValuePairs = default; Dictionary rawData = new Dictionary(); - foreach (var property in element.EnumerateObject()) + foreach (JsonProperty property in element.EnumerateObject()) { if (property.NameEquals("name"u8)) { @@ -124,7 +145,7 @@ internal static ModelWithPersistableOnly DeserializeModelX(JsonElement element, } if (property.NameEquals("fields"u8)) { - fields = property.Value.EnumerateArray().Select(element => element.GetString()).ToList(); + fields = property.Value.EnumerateArray().Select(element => element.GetString()!).ToList(); continue; } if (property.NameEquals("nullProperty"u8)) @@ -139,9 +160,9 @@ internal static ModelWithPersistableOnly DeserializeModelX(JsonElement element, if (property.NameEquals("keyValuePairs"u8)) { Dictionary dictionary = new Dictionary(); - foreach (var property0 in property.Value.EnumerateObject()) + foreach (JsonProperty property0 in property.Value.EnumerateObject()) { - dictionary.Add(property0.Name, property0.Value.GetString()); + dictionary.Add(property0.Name, property0.Value.GetString()!); } keyValuePairs = dictionary; continue; @@ -157,6 +178,7 @@ internal static ModelWithPersistableOnly DeserializeModelX(JsonElement element, rawData.Add(property.Name, BinaryData.FromString(property.Value.GetRawText())); } } + return new ModelWithPersistableOnly(name, xProperty, OptionalProperty.ToNullable(nullProperty), OptionalProperty.ToList(fields), OptionalProperty.ToDictionary(keyValuePairs), rawData); } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.Serialization.cs index e4393e2a69c0..5d97c5262942 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Text.Json; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.cs index 18525a25a432..4fe3a7c6824d 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ApiProfile.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources { /// The ApiProfile. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.Serialization.cs index 7a0a5bcd187d..529b31159dd6 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.ClientModel.Tests.Client.Models.ResourceManager.Resources; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.cs index dd8ead307953..fb71b03c936b 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/AvailabilitySetData.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Tests.Client.Models.ResourceManager.Resources; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.Serialization.cs index 0240a70b3d1e..2d8dcd8a6ea2 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Text.Json; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.cs index c105bc7a0e56..65749933edf0 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeSku.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Compute { /// Describes a virtual machine scale set sku. NOTE: If the new VM SKU is not supported on the hardware the scale set is currently on, you need to deallocate the VMs in the scale set before you modify the SKU name. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.Serialization.cs index 541a8dd96200..e6ee84f6b3e5 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Compute { internal static partial class ComputeStatusLevelTypeExtensions diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.cs index 7730597a4101..4cba4b57bf48 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ComputeStatusLevelType.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Compute { /// The level code. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/CreatedByType.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/CreatedByType.cs index 992f42571c30..0d5c110cb1fe 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/CreatedByType.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/CreatedByType.cs @@ -3,8 +3,6 @@ // -#nullable disable - using System.ComponentModel; namespace System.ClientModel.Tests.Client.Models.ResourceManager diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.Serialization.cs index 01d93a0a3ff3..f99005012fb0 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Globalization; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.cs index 293f238af42e..6e99f9bc8984 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/InstanceViewStatus.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Compute { /// Instance view status. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderAuthorizationConsentState.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderAuthorizationConsentState.cs index 909cdae77b4a..c0da84b79e1e 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderAuthorizationConsentState.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderAuthorizationConsentState.cs @@ -3,8 +3,6 @@ // -#nullable disable - using System.ComponentModel; namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.Serialization.cs index 0e1b113b8137..aa497f3daa05 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.cs index cf36137823a0..fd8d2892166a 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderExtendedLocation.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.Serialization.cs index 6789848e53d7..afaecee28e51 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.cs index 4c5fe551a3b1..e8c7dc0aff0f 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ProviderResourceType.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceData.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceData.cs index dcc3174962ed..faa31fab9213 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceData.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceData.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager { /// Common fields that are returned in the response for all Azure Resource Manager resources. @@ -27,12 +25,15 @@ protected ResourceData(string id, string name, string resourceType, SystemData s } /// Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. - public string Id { get; } + public string? Id { get; } + /// The name of the resource. - public string Name { get; } + public string? Name { get; } + /// The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts". - public string ResourceType { get; } + public string? ResourceType { get; } + /// Azure Resource Manager metadata containing createdBy and modifiedBy information. - public SystemData SystemData { get; } + public SystemData? SystemData { get; } } } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.Serialization.cs index 50cbb69b99ee..b880a16f9f66 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.cs index f4fcff41e23f..8c112fbb20bd 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceProviderData.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.Collections.Generic; using System.Text.Json; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.Serialization.cs index bd5a876f5d33..511100115e64 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.cs index 015e1ee09f64..09a70d5510e2 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAlias.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.Serialization.cs index cd11999862f6..dafe7b325189 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.cs index 5d42a403cb21..e8a2d97e8272 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPath.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathAttributes.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathAttributes.cs index 2cefe596c98d..05f9ffa3da5d 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathAttributes.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathAttributes.cs @@ -3,8 +3,6 @@ // -#nullable disable - using System.ComponentModel; namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.Serialization.cs index 86df483f3e68..ac80a9aaa1a0 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Text.Json; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.cs index 7ca70d986008..5e70b741a0bc 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathMetadata.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources { /// The ResourceTypeAliasPathMetadata. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathTokenType.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathTokenType.cs index e8f1e666039e..d20abd28073a 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathTokenType.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPathTokenType.cs @@ -3,8 +3,6 @@ // -#nullable disable - using System.ComponentModel; namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.Serialization.cs index 15d867604c3a..8df588c3e0f0 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Text.Json; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.cs index c576ac7eb971..904439f2fc38 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPattern.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources { /// The type of the pattern for an alias path. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.Serialization.cs index c044f0ae3d60..def1686d19f2 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources { internal static partial class ResourceTypeAliasPatternTypeExtensions diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.cs index d1304e113d9f..d164dfdd5a86 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasPatternType.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources { /// The type of alias pattern. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.Serialization.cs index 100f1b980c0a..705a52683239 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources { internal static partial class ResourceTypeAliasTypeExtensions diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.cs index ec354ff129d1..b5bf69a849a7 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ResourceTypeAliasType.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager.Resources { /// The type of the alias. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.Serialization.cs index 1f698f7d257f..4dfdb7a2f59f 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.Serialization.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// - -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Globalization; @@ -16,21 +12,22 @@ namespace System.ClientModel.Tests.Client.Models.ResourceManager [JsonConverter(typeof(SystemDataConverter))] public partial class SystemData : IJsonModel { - void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) => Serialize(writer, options); + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions? options) + => Serialize(writer, options); - private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) + private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions? options) { writer.WriteStartObject(); writer.WriteEndObject(); } - internal static SystemData DeserializeSystemData(JsonElement element, ModelReaderWriterOptions options = default) + internal static SystemData DeserializeSystemData(JsonElement element, ModelReaderWriterOptions? options = default) { options ??= ModelReaderWriterHelper.WireOptions; if (element.ValueKind == JsonValueKind.Null) { - return null; + throw new JsonException($"Invalid JSON provided to deserialize type '{nameof(SystemData)}'"); } OptionalProperty createdBy = default; OptionalProperty createdByType = default; @@ -112,7 +109,9 @@ private static void SetProperty(ReadOnlySpan propertyName, ref SystemDataP { reader.Read(); if (reader.TokenType != JsonTokenType.Null) - properties.CreatedBy = reader.GetString(); + { + properties.CreatedBy = reader.GetString()!; + } return; } if (propertyName.SequenceEqual("createdByType"u8)) @@ -126,14 +125,18 @@ private static void SetProperty(ReadOnlySpan propertyName, ref SystemDataP { reader.Read(); if (reader.TokenType != JsonTokenType.Null) - properties.CreatedOn = DateTimeOffset.Parse(reader.GetString(), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); + { + properties.CreatedOn = DateTimeOffset.Parse(reader.GetString()!, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); + } return; } if (propertyName.SequenceEqual("lastModifiedBy"u8)) { reader.Read(); if (reader.TokenType != JsonTokenType.Null) - properties.LastModifiedBy = reader.GetString(); + { + properties.LastModifiedBy = reader.GetString()!; + } return; } if (propertyName.SequenceEqual("lastModifiedByType"u8)) @@ -147,7 +150,9 @@ private static void SetProperty(ReadOnlySpan propertyName, ref SystemDataP { reader.Read(); if (reader.TokenType != JsonTokenType.Null) - properties.LastModifiedOn = DateTimeOffset.Parse(reader.GetString(), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); + { + properties.LastModifiedOn = DateTimeOffset.Parse(reader.GetString()!, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); + } return; } reader.Skip(); @@ -159,9 +164,9 @@ SystemData IPersistableModel.Create(BinaryData data, ModelReaderWrit return DeserializeSystemData(doc.RootElement, options); } - internal partial class SystemDataConverter : JsonConverter + internal partial class SystemDataConverter : JsonConverter { - public override void Write(Utf8JsonWriter writer, SystemData model, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, SystemData? model, JsonSerializerOptions options) { writer.WriteObjectValue(model); } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.cs index cbce4c2804d7..c934611d9d57 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/SystemData.cs @@ -3,8 +3,6 @@ // -#nullable disable - namespace System.ClientModel.Tests.Client.Models.ResourceManager { /// Metadata pertaining to creation and last modification of the resource. diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/TrackedResourceData.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/TrackedResourceData.cs index 0657acf65075..365ff0f5a1bf 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/TrackedResourceData.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/TrackedResourceData.cs @@ -1,17 +1,18 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#nullable disable - -using ClientModel.Tests.ClientShared; using System.Collections.Generic; +using ClientModel.Tests.ClientShared; namespace System.ClientModel.Tests.Client.Models.ResourceManager { /// The resource model definition for an Azure Resource Manager tracked top level resource which has 'tags' and a 'location'. public abstract partial class TrackedResourceData : ResourceData { - internal TrackedResourceData() { } + internal TrackedResourceData() + { + Tags = new OptionalDictionary(); + } /// Initializes a new instance of TrackedResource. /// The geo-location where the resource lives. @@ -36,7 +37,23 @@ protected TrackedResourceData(string id, string name, string resourceType, Syste /// Resource tags. public IDictionary Tags { get; } + + private string? _location; /// The geo-location where the resource lives. - public string Location { get; set; } + public string Location + { + get + { + AssertHasValue(_location, nameof(Location)); + return _location!; + } + set { _location = value; } + } + + private void AssertHasValue(T? value, string name) + { + if (value is null) + throw new ArgumentNullException(name); + } } } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.Serialization.cs index 270512877fe6..edea5bb6144d 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.Serialization.cs @@ -41,11 +41,11 @@ private void Serialize(Utf8JsonWriter writer, ModelReaderWriterOptions options) /// /// The JSON element to be deserialized. /// Deserialized WritableSubResource object. - internal static WritableSubResource DeserializeWritableSubResource(JsonElement element, ModelReaderWriterOptions options = default) + internal static WritableSubResource DeserializeWritableSubResource(JsonElement element, ModelReaderWriterOptions? options = default) { options ??= ModelReaderWriterHelper.WireOptions; - string id = default; + string? id = default; foreach (var property in element.EnumerateObject()) { if (property.NameEquals("id")) @@ -78,7 +78,9 @@ private static void SetProperty(ReadOnlySpan propertyName, ref WritableSub { reader.Read(); if (reader.TokenType != JsonTokenType.Null) - properties.Id = reader.GetString(); + { + properties.Id = reader.GetString()!; + } return; } reader.Skip(); diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.cs index 4e758acb07c7..1c9d37256537 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/WritableSubResource.cs @@ -17,7 +17,7 @@ public WritableSubResource() /// Initializes a new instance of . /// ARM resource Id. - protected internal WritableSubResource(string id) + protected internal WritableSubResource(string? id) { Id = id; } @@ -26,6 +26,6 @@ protected internal WritableSubResource(string id) /// Gets or sets the ARM resource identifier. /// /// - public string Id { get; set; } + public string? Id { get; set; } } } diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.Serialization.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.Serialization.cs index 34cb3f05eacb..84567c67a8df 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.Serialization.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.Serialization.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.ClientModel.Primitives; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.cs b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.cs index b04f38867584..b981cc599bd4 100644 --- a/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.cs +++ b/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/ServiceModels/ZoneMapping.cs @@ -3,8 +3,6 @@ // -#nullable disable - using ClientModel.Tests.ClientShared; using System.Collections.Generic; diff --git a/sdk/core/System.ClientModel/tests/client/System.ClientModel.Tests.Client.csproj b/sdk/core/System.ClientModel/tests/client/System.ClientModel.Tests.Client.csproj index e88b31806b70..8a60f3bfaac5 100644 --- a/sdk/core/System.ClientModel/tests/client/System.ClientModel.Tests.Client.csproj +++ b/sdk/core/System.ClientModel/tests/client/System.ClientModel.Tests.Client.csproj @@ -4,6 +4,7 @@ Test client code for use in System.ClientModel test libraries. $(RequiredTargetFrameworks) true + enable diff --git a/sdk/core/System.ClientModel/tests/client/TestData.cs b/sdk/core/System.ClientModel/tests/client/TestData.cs index 9fb857da85f8..26e0afcca774 100644 --- a/sdk/core/System.ClientModel/tests/client/TestData.cs +++ b/sdk/core/System.ClientModel/tests/client/TestData.cs @@ -10,7 +10,8 @@ public static class TestData { public static string GetLocation(string fileName) { - string testsLocation = Directory.GetParent(typeof(TestData).Assembly.Location).FullName; + string? testsLocation = (Directory.GetParent(typeof(TestData).Assembly.Location)?.FullName) + ?? throw new InvalidOperationException("Failed to find test location"); StringBuilder builder = new StringBuilder(); int indexAfter = testsLocation.IndexOf(".Tests") + 6; builder.Append(testsLocation.Substring(0, indexAfter)); diff --git a/sdk/core/System.ClientModel/tests/internal/ModelReaderWriter/JsonModelConverterTests.cs b/sdk/core/System.ClientModel/tests/internal/ModelReaderWriter/JsonModelConverterTests.cs index cc480efbf558..1b4a149b5f26 100644 --- a/sdk/core/System.ClientModel/tests/internal/ModelReaderWriter/JsonModelConverterTests.cs +++ b/sdk/core/System.ClientModel/tests/internal/ModelReaderWriter/JsonModelConverterTests.cs @@ -41,13 +41,8 @@ public void ValidateJsonExceptionBinaryData(BinaryData data) [TestCaseSource(typeof(ReaderWriterTestSource), "EmptyObjectBinaryData")] public void ValidateEmptyObjectBinaryData(BinaryData data) { - ModelX? x = JsonSerializer.Deserialize(data, _options); - Assert.IsNotNull(x); - Assert.IsNull(x!.Kind); - - object? obj = JsonSerializer.Deserialize(data, typeof(ModelX), _options); - Assert.IsNotNull(obj); - Assert.IsNull(((ModelX)obj!).Kind); + Assert.Throws(() => ModelReaderWriter.Read(data)); + Assert.Throws(() => ModelReaderWriter.Read(data, typeof(ModelX))); } [TestCase("J")] From 10be5d25edc5553a4ad5a279fb5ca01c086fbfbb Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 14 Feb 2024 14:59:14 -0800 Subject: [PATCH 20/47] update --- sdk/core/Azure.Core/Azure.Core.sln | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/sdk/core/Azure.Core/Azure.Core.sln b/sdk/core/Azure.Core/Azure.Core.sln index e7b54032ec97..194fb4694ad2 100644 --- a/sdk/core/Azure.Core/Azure.Core.sln +++ b/sdk/core/Azure.Core/Azure.Core.sln @@ -53,15 +53,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.Tests.Public", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.Tests.Common", "tests\common\Azure.Core.Tests.Common.csproj", "{0EEDF53F-120A-45B1-8468-A97A0D46DBAC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel", "..\System.ClientModel\src\System.ClientModel.csproj", "{0EDC2FDC-6326-431D-86D2-02997F341934}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel", "..\System.ClientModel\src\System.ClientModel.csproj", "{70B67A2C-3CA5-44A0-AF2D-51241A0076E2}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests", "..\System.ClientModel\tests\System.ClientModel.Tests.csproj", "{55DBB83B-70E5-4591-BB74-668D8662FECB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Client", "..\System.ClientModel\tests\client\System.ClientModel.Tests.Client.csproj", "{062EA07F-5F75-4447-9453-44FF8A99EF1B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Client", "..\System.ClientModel\tests\client\System.ClientModel.Tests.Client.csproj", "{82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal", "..\System.ClientModel\tests\internal\System.ClientModel.Tests.Internal.csproj", "{23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal", "..\System.ClientModel\tests\internal\System.ClientModel.Tests.Internal.csproj", "{F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal.Perf", "..\System.ClientModel\tests\internal.perf\System.ClientModel.Tests.Internal.Perf.csproj", "{2E79B809-C520-4A07-8BC2-23C43B4D3C35}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests.Internal.Perf", "..\System.ClientModel\tests\internal.perf\System.ClientModel.Tests.Internal.Perf.csproj", "{14F5E486-2C03-4293-ACA7-47B3E069956E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.ClientModel.Tests", "..\System.ClientModel\tests\System.ClientModel.Tests.csproj", "{F317D37D-AA38-4557-A724-6ADA56281B77}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -141,26 +141,26 @@ Global {0EEDF53F-120A-45B1-8468-A97A0D46DBAC}.Debug|Any CPU.Build.0 = Debug|Any CPU {0EEDF53F-120A-45B1-8468-A97A0D46DBAC}.Release|Any CPU.ActiveCfg = Release|Any CPU {0EEDF53F-120A-45B1-8468-A97A0D46DBAC}.Release|Any CPU.Build.0 = Release|Any CPU - {0EDC2FDC-6326-431D-86D2-02997F341934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EDC2FDC-6326-431D-86D2-02997F341934}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EDC2FDC-6326-431D-86D2-02997F341934}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EDC2FDC-6326-431D-86D2-02997F341934}.Release|Any CPU.Build.0 = Release|Any CPU - {55DBB83B-70E5-4591-BB74-668D8662FECB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55DBB83B-70E5-4591-BB74-668D8662FECB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55DBB83B-70E5-4591-BB74-668D8662FECB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55DBB83B-70E5-4591-BB74-668D8662FECB}.Release|Any CPU.Build.0 = Release|Any CPU - {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Debug|Any CPU.Build.0 = Debug|Any CPU - {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Release|Any CPU.ActiveCfg = Release|Any CPU - {82EA00A5-B7C2-4F2F-A2CA-72F2FC43C086}.Release|Any CPU.Build.0 = Release|Any CPU - {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1C58999-5F6E-4FFD-B3F3-A7DF64935FD9}.Release|Any CPU.Build.0 = Release|Any CPU - {14F5E486-2C03-4293-ACA7-47B3E069956E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {14F5E486-2C03-4293-ACA7-47B3E069956E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {14F5E486-2C03-4293-ACA7-47B3E069956E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {14F5E486-2C03-4293-ACA7-47B3E069956E}.Release|Any CPU.Build.0 = Release|Any CPU + {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70B67A2C-3CA5-44A0-AF2D-51241A0076E2}.Release|Any CPU.Build.0 = Release|Any CPU + {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {062EA07F-5F75-4447-9453-44FF8A99EF1B}.Release|Any CPU.Build.0 = Release|Any CPU + {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23F1EA7A-8576-4877-9B1D-1F1FDADB0EE9}.Release|Any CPU.Build.0 = Release|Any CPU + {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E79B809-C520-4A07-8BC2-23C43B4D3C35}.Release|Any CPU.Build.0 = Release|Any CPU + {F317D37D-AA38-4557-A724-6ADA56281B77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F317D37D-AA38-4557-A724-6ADA56281B77}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F317D37D-AA38-4557-A724-6ADA56281B77}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F317D37D-AA38-4557-A724-6ADA56281B77}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From de10745dc8a8d72a9486d088a336c5b9533b3379 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 14 Feb 2024 15:19:44 -0800 Subject: [PATCH 21/47] updates --- sdk/core/Azure.Core/samples/Configuration.md | 1 - .../Internal/AzureBaseBuffersExtensions.cs | 36 ------------------- .../Azure.Core/src/Pipeline/HttpPipeline.cs | 6 +--- .../src/Pipeline/HttpWebRequestTransport.cs | 2 -- sdk/core/Azure.Core/src/Response.cs | 5 +-- .../tests/HttpPipelineMessageTest.cs | 2 -- 6 files changed, 2 insertions(+), 50 deletions(-) diff --git a/sdk/core/Azure.Core/samples/Configuration.md b/sdk/core/Azure.Core/samples/Configuration.md index 3c06406e524c..1aa9263af641 100644 --- a/sdk/core/Azure.Core/samples/Configuration.md +++ b/sdk/core/Azure.Core/samples/Configuration.md @@ -40,7 +40,6 @@ internal class GlobalTimeoutRetryPolicy : RetryPolicy { return ShouldRetryInternalAsync(message, exception, false).EnsureCompleted(); } - protected override ValueTask ShouldRetryAsync(HttpMessage message, Exception exception) { return ShouldRetryInternalAsync(message, exception, true); diff --git a/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs b/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs index 9d1410e65b11..cede9eade4c3 100644 --- a/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs +++ b/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs @@ -93,16 +93,6 @@ public static async Task WriteAsync(this Stream stream, ReadOnlySequence b public static async Task CopyToAsync(this Stream source, Stream destination, CancellationToken cancellationToken) { - //using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - //cts.CancelAfter(timeout); - - //// If cancellation is possible (whether due to network timeout or a user cancellation token being passed), then - //// register callback to dispose the stream on cancellation. - //if (timeout != Timeout.InfiniteTimeSpan || cancellationToken.CanBeCanceled) - //{ - // cts.Token.Register(state => ((Stream?)state)?.Dispose(), source); - //} - byte[] buffer = ArrayPool.Shared.Rent(DefaultCopyBufferSize); try @@ -117,14 +107,6 @@ public static async Task CopyToAsync(this Stream source, Stream destination, Can await destination.WriteAsync(new ReadOnlyMemory(buffer, 0, bytesRead), cancellationToken).ConfigureAwait(false); } } - //catch (Exception ex) when (ex is ObjectDisposedException - // or IOException - // or OperationCanceledException - // or NotSupportedException) - //{ - // CancellationHelper.ThrowIfCancellationRequestedOrTimeout(cancellationToken, cts.Token, ex, timeout); - // throw; - //} finally { ArrayPool.Shared.Return(buffer); @@ -133,16 +115,6 @@ public static async Task CopyToAsync(this Stream source, Stream destination, Can public static void CopyTo(this Stream source, Stream destination, CancellationToken cancellationToken) { - //using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - //cts.CancelAfter(timeout); - - //// If cancellation is possible (whether due to network timeout or a user cancellation token being passed), then - //// register callback to dispose the stream on cancellation. - //if (timeout != Timeout.InfiniteTimeSpan || cancellationToken.CanBeCanceled) - //{ - // cts.Token.Register(state => ((Stream?)state)?.Dispose(), source); - //} - byte[] buffer = ArrayPool.Shared.Rent(DefaultCopyBufferSize); try @@ -154,14 +126,6 @@ public static void CopyTo(this Stream source, Stream destination, CancellationTo destination.Write(buffer, 0, read); } } - //catch (Exception ex) when (ex is ObjectDisposedException - // or IOException - // or OperationCanceledException - // or NotSupportedException) - //{ - // CancellationHelper.ThrowIfCancellationRequestedOrTimeout(cancellationToken, cts.Token, ex, timeout); - // throw; - //} finally { ArrayPool.Shared.Return(buffer); diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs index 61bb9850a61f..a8e24702f5ff 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs @@ -103,11 +103,7 @@ public Request CreateRequest() /// /// The message. public HttpMessage CreateMessage() - { - Request request = CreateRequest(); - HttpMessage message = new(request, ResponseClassifier); - return message; - } + => new HttpMessage(CreateRequest(), ResponseClassifier); /// /// diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs index 77b0501fc8fb..f3153bbe9011 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs @@ -328,8 +328,6 @@ public override Stream? ContentStream } } - // TODO: Implement Content and ReadContent - public override string ClientRequestId { get; set; } public override void Dispose() diff --git a/sdk/core/Azure.Core/src/Response.cs b/sdk/core/Azure.Core/src/Response.cs index 93500999122d..c09977ba5213 100644 --- a/sdk/core/Azure.Core/src/Response.cs +++ b/sdk/core/Azure.Core/src/Response.cs @@ -42,10 +42,7 @@ public abstract class Response : PipelineResponse /// [EditorBrowsable(EditorBrowsableState.Never)] protected override PipelineResponseHeaders GetHeadersCore() - { - // TODO: we'll need to add an adapter in case someone were to override this. - throw new NotImplementedException(); - } + => throw new NotImplementedException("Subtypes must implement this method."); /// /// Gets the contents of HTTP response, if it is available. diff --git a/sdk/core/Azure.Core/tests/HttpPipelineMessageTest.cs b/sdk/core/Azure.Core/tests/HttpPipelineMessageTest.cs index be3cbd411af2..7fd9387161db 100644 --- a/sdk/core/Azure.Core/tests/HttpPipelineMessageTest.cs +++ b/sdk/core/Azure.Core/tests/HttpPipelineMessageTest.cs @@ -20,7 +20,6 @@ public void DisposeNoopsForNullResponse() var requestMock = new Mock(); HttpMessage message = new HttpMessage(requestMock.Object, _classifier); message.Dispose(); - requestMock.Verify(r => r.Dispose(), Times.Once); } @@ -32,7 +31,6 @@ public void DisposingMessageDisposesTheRequestAndResponse() HttpMessage message = new HttpMessage(requestMock.Object, _classifier); message.Response = responseMock.Object; message.Dispose(); - requestMock.Verify(r => r.Dispose(), Times.Once); responseMock.Verify(r => r.Dispose(), Times.Once); } From f384e3ce488fa604ba0103f73eb0a6f802a2cf7c Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 14 Feb 2024 16:40:16 -0800 Subject: [PATCH 22/47] pr fb --- sdk/core/Azure.Core/CHANGELOG.md | 4 +++- sdk/core/Azure.Core/src/Azure.Core.csproj | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sdk/core/Azure.Core/CHANGELOG.md b/sdk/core/Azure.Core/CHANGELOG.md index 0ba7e43a08cb..53c5e0035782 100644 --- a/sdk/core/Azure.Core/CHANGELOG.md +++ b/sdk/core/Azure.Core/CHANGELOG.md @@ -1,6 +1,6 @@ # Release History -## 1.38.0-beta.1 (Unreleased) +## 2.0.0-beta.1 (Unreleased) ### Features Added @@ -10,6 +10,8 @@ ### Other Changes +- Moved Azure.Core types to use functionality implemented in System.ClientModel library. + - Additional Azure data centers are now included in `AzureLocation`. The following were added: - China East 3 - China North 3 diff --git a/sdk/core/Azure.Core/src/Azure.Core.csproj b/sdk/core/Azure.Core/src/Azure.Core.csproj index 92749ce9879e..6b80ccabb6d6 100644 --- a/sdk/core/Azure.Core/src/Azure.Core.csproj +++ b/sdk/core/Azure.Core/src/Azure.Core.csproj @@ -2,7 +2,7 @@ This is the implementation of the Azure Client Pipeline Microsoft Azure Client Pipeline - 1.38.0-beta.1 + 2.0.0-beta.1 1.37.0 Microsoft Azure Client Pipeline From 4cbd1eba6a77eb1ce20ac237fbb6e572868cffd1 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 14 Feb 2024 16:42:27 -0800 Subject: [PATCH 23/47] fix --- .../src/Pipeline/HttpClientTransport.Response.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs index 337a87892436..d654af840417 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs @@ -48,7 +48,7 @@ public override BinaryData Content { get { - ResetContentStreamPosition(_pipelineResponse); + HttpClientTransportResponse.ResetContentStreamPosition(_pipelineResponse); return _pipelineResponse.Content; } } @@ -79,13 +79,14 @@ protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(tr public override void Dispose() { PipelineResponse response = _pipelineResponse; - ResetContentStreamPosition(response); + HttpClientTransportResponse.ResetContentStreamPosition(response); response?.Dispose(); } - private void ResetContentStreamPosition(PipelineResponse response) + private static void ResetContentStreamPosition(PipelineResponse response) { - if (response.ContentStream is MemoryStream stream && stream.Position != 0) + if (response.ContentStream is MemoryStream stream && response.ContentStream.CanSeek && + stream.Position != 0) { // Azure.Core Response has a contract that ContentStream can be read // without setting position back to 0. This means if ReadContent is From b3646a8a5452aa6275d53eec9717d66b80059783 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Thu, 15 Feb 2024 08:39:58 -0800 Subject: [PATCH 24/47] nit --- .../Azure.Core/src/Pipeline/HttpClientTransport.Response.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs index d654af840417..4fe70a9e5924 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs @@ -48,7 +48,7 @@ public override BinaryData Content { get { - HttpClientTransportResponse.ResetContentStreamPosition(_pipelineResponse); + ResetContentStreamPosition(_pipelineResponse); return _pipelineResponse.Content; } } @@ -79,7 +79,7 @@ protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(tr public override void Dispose() { PipelineResponse response = _pipelineResponse; - HttpClientTransportResponse.ResetContentStreamPosition(response); + ResetContentStreamPosition(response); response?.Dispose(); } From 2f56c71368b5378aff6160e5d2453fe6acf8f53c Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 26 Feb 2024 12:13:17 -0800 Subject: [PATCH 25/47] update after merge from main --- sdk/core/Azure.Core/CHANGELOG.md | 2 - sdk/core/Azure.Core/api/Azure.Core.net461.cs | 135 +++++++++--------- sdk/core/Azure.Core/api/Azure.Core.net472.cs | 135 +++++++++--------- sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 135 +++++++++--------- .../api/Azure.Core.netstandard2.0.cs | 135 +++++++++--------- sdk/core/Azure.Core/src/Azure.Core.csproj | 2 +- .../Pipeline/HttpClientTransport.Request.cs | 62 ++++---- .../Pipeline/HttpClientTransport.Response.cs | 8 +- sdk/core/Azure.Core/src/Request.cs | 64 ++++----- .../Azure.Core/src/RequestFailedException.cs | 4 +- sdk/core/Azure.Core/src/Response.cs | 35 ++--- .../HttpClientPipelineTransport.Response.cs | 6 +- 12 files changed, 362 insertions(+), 361 deletions(-) diff --git a/sdk/core/Azure.Core/CHANGELOG.md b/sdk/core/Azure.Core/CHANGELOG.md index 7d2607054819..0c4a1b7a933c 100644 --- a/sdk/core/Azure.Core/CHANGELOG.md +++ b/sdk/core/Azure.Core/CHANGELOG.md @@ -20,8 +20,6 @@ ### Other Changes -- Moved Azure.Core types to use functionality implemented in System.ClientModel library. - - Additional Azure data centers are now included in `AzureLocation`. The following were added: - China East 3 - China North 3 diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index 7d6246afcef8..b060f6118980 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -209,47 +209,45 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public override System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } + protected override bool IsErrorCore { get { throw null; } set { } } + public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } public override string ToString() { throw null; } @@ -265,7 +263,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -382,18 +382,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -488,23 +489,18 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -542,28 +538,31 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineRequestHeaders HeadersCore { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + protected override string MethodCore { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + protected override System.Uri? UriCore { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); protected internal abstract bool RemoveHeader(string name); protected internal virtual void SetHeader(string name, string value) { } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -573,13 +572,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -703,13 +699,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -740,6 +740,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1040,11 +1041,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1080,14 +1083,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index 7d6246afcef8..b060f6118980 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -209,47 +209,45 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public override System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } + protected override bool IsErrorCore { get { throw null; } set { } } + public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } public override string ToString() { throw null; } @@ -265,7 +263,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -382,18 +382,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -488,23 +489,18 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -542,28 +538,31 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineRequestHeaders HeadersCore { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + protected override string MethodCore { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + protected override System.Uri? UriCore { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); protected internal abstract bool RemoveHeader(string name); protected internal virtual void SetHeader(string name, string value) { } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -573,13 +572,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -703,13 +699,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -740,6 +740,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1040,11 +1041,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1080,14 +1083,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index 948e617f1186..a0e29c87f5a0 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -209,47 +209,45 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public override System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } + protected override bool IsErrorCore { get { throw null; } set { } } + public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } public override string ToString() { throw null; } @@ -265,7 +263,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -382,18 +382,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -488,23 +489,18 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -542,28 +538,31 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineRequestHeaders HeadersCore { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + protected override string MethodCore { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + protected override System.Uri? UriCore { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); protected internal abstract bool RemoveHeader(string name); protected internal virtual void SetHeader(string name, string value) { } protected internal abstract bool TryGetHeader(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value); protected internal abstract bool TryGetHeaderValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -576,13 +575,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -706,13 +702,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -743,6 +743,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1044,11 +1045,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1085,14 +1088,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index 7d6246afcef8..b060f6118980 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -23,12 +23,11 @@ public static partial class AzureCoreExtensions public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public partial class AzureKeyCredential + public partial class AzureKeyCredential : System.ClientModel.ApiKeyCredential { - public AzureKeyCredential(string key) { } + public AzureKeyCredential(string key) : base (default(string)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public string Key { get { throw null; } } - public void Update(string key) { } } public partial class AzureNamedKeyCredential { @@ -115,16 +114,17 @@ public MatchConditions() { } public Azure.ETag? IfMatch { get { throw null; } set { } } public Azure.ETag? IfNoneMatch { get { throw null; } set { } } } - public abstract partial class NullableResponse + public abstract partial class NullableResponse : System.ClientModel.ClientResult { - protected NullableResponse() { } - public abstract bool HasValue { get; } - public abstract T? Value { get; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + protected NullableResponse() : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + protected NullableResponse(T? value, Azure.Response response) : base (default(T), default(System.ClientModel.Primitives.PipelineResponse)) { } + public virtual bool HasValue { get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } - public abstract Azure.Response GetRawResponse(); + public virtual new Azure.Response GetRawResponse() { throw null; } public override string ToString() { throw null; } } public abstract partial class Operation @@ -209,47 +209,45 @@ public RequestConditions() { } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } public System.DateTimeOffset? IfUnmodifiedSince { get { throw null; } set { } } } - public partial class RequestContext + public partial class RequestContext : System.ClientModel.Primitives.RequestOptions { public RequestContext() { } - public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } } - public Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } + public new Azure.ErrorOptions ErrorOptions { get { throw null; } set { } } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } - public partial class RequestFailedException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable { - public RequestFailedException(Azure.Response response) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException) { } - public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) { } + public RequestFailedException(Azure.Response response) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(Azure.Response response, System.Exception? innerException, Azure.Core.RequestFailedDetailsParser? detailsParser) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message) { } + public RequestFailedException(int status, string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) { } - protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public RequestFailedException(string message) { } - public RequestFailedException(string message, System.Exception? innerException) { } + public RequestFailedException(int status, string message, string? errorCode, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + protected RequestFailedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } + public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public int Status { get { throw null; } } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public Azure.Response? GetRawResponse() { throw null; } + public new Azure.Response? GetRawResponse() { throw null; } } - public abstract partial class Response : System.IDisposable + public abstract partial class Response : System.ClientModel.Primitives.PipelineResponse { protected Response() { } public abstract string ClientRequestId { get; set; } - public virtual System.BinaryData Content { get { throw null; } } - public abstract System.IO.Stream? ContentStream { get; set; } - public virtual Azure.Core.ResponseHeaders Headers { get { throw null; } } - public virtual bool IsError { get { throw null; } } - public abstract string ReasonPhrase { get; } - public abstract int Status { get; } + public override System.BinaryData Content { get { throw null; } } + public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } + protected override bool IsErrorCore { get { throw null; } set { } } + public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); public static Azure.Response FromValue(T value, Azure.Response response) { throw null; } public override string ToString() { throw null; } @@ -265,7 +263,9 @@ public ResponseError(string? code, string? message) { } } public abstract partial class Response : Azure.NullableResponse { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected Response() { } + protected Response(T value, Azure.Response response) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool HasValue { get { throw null; } } public override T Value { get { throw null; } } @@ -382,18 +382,19 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions + public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } + public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -488,23 +489,18 @@ public static partial class Names public static string XMsRequestId { get { throw null; } } } } - public sealed partial class HttpMessage : System.IDisposable + public sealed partial class HttpMessage : System.ClientModel.Primitives.PipelineMessage { - public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) { } - public bool BufferResponse { get { throw null; } set { } } - public System.Threading.CancellationToken CancellationToken { get { throw null; } } + public HttpMessage(Azure.Core.Request request, Azure.Core.ResponseClassifier responseClassifier) : base (default(System.ClientModel.Primitives.PipelineRequest)) { } public bool HasResponse { get { throw null; } } - public System.TimeSpan? NetworkTimeout { get { throw null; } set { } } public Azure.Core.MessageProcessingContext ProcessingContext { get { throw null; } } - public Azure.Core.Request Request { get { throw null; } } - public Azure.Response Response { get { throw null; } set { } } - public Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } - public void Dispose() { } + public new Azure.Core.Request Request { get { throw null; } } + public new Azure.Response Response { get { throw null; } set { } } + public new Azure.Core.ResponseClassifier ResponseClassifier { get { throw null; } set { } } + public new Azure.Response? ExtractResponse() { throw null; } public System.IO.Stream? ExtractResponseContent() { throw null; } public void SetProperty(string name, object value) { } - public void SetProperty(System.Type type, object value) { } public bool TryGetProperty(string name, out object? value) { throw null; } - public bool TryGetProperty(System.Type type, out object? value) { throw null; } } public enum HttpPipelinePosition { @@ -542,28 +538,31 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf string System.ClientModel.Primitives.IPersistableModel.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } System.BinaryData System.ClientModel.Primitives.IPersistableModel.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; } } - public abstract partial class Request : System.IDisposable + public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public abstract string ClientRequestId { get; set; } - public virtual Azure.Core.RequestContent? Content { get { throw null; } set { } } - public Azure.Core.RequestHeaders Headers { get { throw null; } } - public virtual Azure.Core.RequestMethod Method { get { throw null; } set { } } - public virtual Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + public virtual string ClientRequestId { get { throw null; } set { } } + public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } + protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } + public new Azure.Core.RequestHeaders Headers { get { throw null; } } + protected override System.ClientModel.Primitives.PipelineRequestHeaders HeadersCore { get { throw null; } } + public virtual new Azure.Core.RequestMethod Method { get { throw null; } set { } } + protected override string MethodCore { get { throw null; } set { } } + public virtual new Azure.Core.RequestUriBuilder Uri { get { throw null; } set { } } + protected override System.Uri? UriCore { get { throw null; } set { } } protected internal abstract void AddHeader(string name, string value); protected internal abstract bool ContainsHeader(string name); - public abstract void Dispose(); protected internal abstract System.Collections.Generic.IEnumerable EnumerateHeaders(); protected internal abstract bool RemoveHeader(string name); protected internal virtual void SetHeader(string name, string value) { } protected internal abstract bool TryGetHeader(string name, out string? value); protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable? values); } - public abstract partial class RequestContent : System.IDisposable + public abstract partial class RequestContent : System.ClientModel.BinaryContent { protected RequestContent() { } public static Azure.Core.RequestContent Create(Azure.Core.Serialization.DynamicData content) { throw null; } - public static Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } + public static new Azure.Core.RequestContent Create(System.BinaryData content) { throw null; } public static Azure.Core.RequestContent Create(System.Buffers.ReadOnlySequence bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes) { throw null; } public static Azure.Core.RequestContent Create(byte[] bytes, int index, int length) { throw null; } @@ -573,13 +572,10 @@ protected RequestContent() { } public static Azure.Core.RequestContent Create(object serializable, Azure.Core.Serialization.ObjectSerializer? serializer) { throw null; } public static Azure.Core.RequestContent Create(System.ReadOnlyMemory bytes) { throw null; } public static Azure.Core.RequestContent Create(string content) { throw null; } - public abstract void Dispose(); + public static Azure.Core.RequestContent Create(T model, System.ClientModel.Primitives.ModelReaderWriterOptions? options = null) where T : System.ClientModel.Primitives.IPersistableModel { throw null; } public static implicit operator Azure.Core.RequestContent (Azure.Core.Serialization.DynamicData content) { throw null; } public static implicit operator Azure.Core.RequestContent (System.BinaryData content) { throw null; } public static implicit operator Azure.Core.RequestContent (string content) { throw null; } - public abstract bool TryComputeLength(out long length); - public abstract void WriteTo(System.IO.Stream stream, System.Threading.CancellationToken cancellation); - public abstract System.Threading.Tasks.Task WriteToAsync(System.IO.Stream stream, System.Threading.CancellationToken cancellation); } public abstract partial class RequestFailedDetailsParser { @@ -703,13 +699,17 @@ public abstract partial class ResponseClassificationHandler protected ResponseClassificationHandler() { } public abstract bool TryClassify(Azure.Core.HttpMessage message, out bool isError); } - public partial class ResponseClassifier + public partial class ResponseClassifier : System.ClientModel.Primitives.PipelineMessageClassifier { public ResponseClassifier() { } public virtual bool IsErrorResponse(Azure.Core.HttpMessage message) { throw null; } public virtual bool IsRetriable(Azure.Core.HttpMessage message, System.Exception exception) { throw null; } public virtual bool IsRetriableException(System.Exception exception) { throw null; } public virtual bool IsRetriableResponse(Azure.Core.HttpMessage message) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, out bool isError) { throw null; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] + public sealed override bool TryClassify(System.ClientModel.Primitives.PipelineMessage message, System.Exception? exception, out bool isRetriable) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ResponseHeaders : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable @@ -740,6 +740,7 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier @@ -1040,11 +1041,13 @@ public HttpPipelineOptions(Azure.Core.ClientOptions options) { } public Azure.Core.RequestFailedDetailsParser RequestFailedDetailsParser { get { throw null; } set { } } public Azure.Core.ResponseClassifier? ResponseClassifier { get { throw null; } set { } } } - public abstract partial class HttpPipelinePolicy + public abstract partial class HttpPipelinePolicy : System.ClientModel.Primitives.PipelinePolicy { protected HttpPipelinePolicy() { } public abstract void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override void Process(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { } public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline); + public sealed override System.Threading.Tasks.ValueTask ProcessAsync(System.ClientModel.Primitives.PipelineMessage message, System.Collections.Generic.IReadOnlyList pipeline, int currentIndex) { throw null; } protected static void ProcessNext(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } protected static System.Threading.Tasks.ValueTask ProcessNextAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } @@ -1080,14 +1083,14 @@ public static void SetAllowAutoRedirect(Azure.Core.HttpMessage message, bool all public partial class RetryPolicy : Azure.Core.Pipeline.HttpPipelinePolicy { public RetryPolicy(int maxRetries = 3, Azure.Core.DelayStrategy? delayStrategy = null) { } - protected internal virtual void OnRequestSent(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } - protected internal virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } - protected internal virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnRequestSent(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnRequestSentAsync(Azure.Core.HttpMessage message) { throw null; } + protected virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } + protected virtual System.Threading.Tasks.ValueTask OnSendingRequestAsync(Azure.Core.HttpMessage message) { throw null; } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } - protected internal virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } - protected internal virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual bool ShouldRetry(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } + protected virtual System.Threading.Tasks.ValueTask ShouldRetryAsync(Azure.Core.HttpMessage message, System.Exception? exception) { throw null; } } public partial class ServerCertificateCustomValidationArgs { diff --git a/sdk/core/Azure.Core/src/Azure.Core.csproj b/sdk/core/Azure.Core/src/Azure.Core.csproj index 1448bab9211b..3d12d5114b46 100644 --- a/sdk/core/Azure.Core/src/Azure.Core.csproj +++ b/sdk/core/Azure.Core/src/Azure.Core.csproj @@ -4,7 +4,7 @@ Microsoft Azure Client Pipeline 2.0.0-beta.1 - 1.37.0 + 1.38.0 Microsoft Azure Client Pipeline enable $(DefineConstants);AZURE_NULLABLE;HAS_INTERNALS_VISIBLE_CORE diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs index 9065921ce83c..682e91649632 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs @@ -32,7 +32,7 @@ public HttpClientTransportRequest(PipelineRequest request) _pipelineRequest = request; // Initialize duplicated properties on base type from adapted request. - base.SetMethodCore(request.Method); + base.MethodCore = request.Method; // Uri and Content are initialized to null in constructor // so don't need to be set here. @@ -40,46 +40,50 @@ public HttpClientTransportRequest(PipelineRequest request) #region Adapt PipelineResponse to inherit functional implementation from ClientModel - protected override string GetMethodCore() - => _pipelineRequest.Method; - - protected override void SetMethodCore(string method) + protected override string MethodCore { - // Update fields on both Request and PipelineRequest. - base.SetMethodCore(method); - _pipelineRequest.Method = method; + get => _pipelineRequest.Method; + set + { + // Update fields on both Request and PipelineRequest. + base.MethodCore = value; + _pipelineRequest.Method = value; + } } - - protected override Uri GetUriCore() + protected override Uri? UriCore { - Uri uri = Uri.ToUri(); + get + { + Uri uri = Uri.ToUri(); - // Lazily update the value on the adapted PipelineRequest. - SetUriCore(uri); + // Lazily update the value on the adapted PipelineRequest. + UriCore = uri; - return uri; - } + return uri; + } - protected override void SetUriCore(Uri uri) - { - // Update fields on both Request and PipelineRequest. - base.SetUriCore(uri); - _pipelineRequest.Uri = uri; + set + { + // Update fields on both Request and PipelineRequest. + base.UriCore = value; + _pipelineRequest.Uri = value; + } } - protected override BinaryContent? GetContentCore() - => _pipelineRequest.Content; + protected override PipelineRequestHeaders HeadersCore + => _pipelineRequest.Headers; - protected override void SetContentCore(BinaryContent? content) + protected override BinaryContent? ContentCore { - // Update Content fields on both Request and PipelineRequest. - base.SetContentCore(content); - _pipelineRequest.Content = content; + get => _pipelineRequest.Content; + set + { + // Update Content fields on both Request and PipelineRequest. + base.ContentCore = value; + _pipelineRequest.Content = value; + } } - protected override PipelineRequestHeaders GetHeadersCore() - => _pipelineRequest.Headers; - #endregion #region Implement Azure.Core Request abstract methods diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs index 4fe70a9e5924..fed393a61548 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs @@ -53,11 +53,11 @@ public override BinaryData Content } } - public override BinaryData ReadContent(CancellationToken cancellationToken = default) - => _pipelineResponse.ReadContent(cancellationToken); + public override BinaryData BufferContent(CancellationToken cancellationToken = default) + => _pipelineResponse.BufferContent(cancellationToken); - public override async ValueTask ReadContentAsync(CancellationToken cancellationToken = default) - => await base.ReadContentAsync(cancellationToken).ConfigureAwait(false); + public override async ValueTask BufferContentAsync(CancellationToken cancellationToken = default) + => await base.BufferContentAsync(cancellationToken).ConfigureAwait(false); protected internal override bool ContainsHeader(string name) => _pipelineResponse.Headers.TryGetValue(name, out _); diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index d71dde70c4ee..02fd5210b4ea 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -29,7 +29,7 @@ public abstract class Request : PipelineRequest public new virtual RequestMethod Method { get => _method; - set => SetMethodCore(value.Method); + set => MethodCore = value.Method; } /// @@ -51,8 +51,8 @@ public abstract class Request : PipelineRequest /// public new virtual RequestContent? Content { - get => (RequestContent?)GetContentCore(); - set => SetContentCore(value); + get => (RequestContent?)ContentCore; + set => ContentCore = value; } /// @@ -80,50 +80,44 @@ public virtual string ClientRequestId /// /// TBD. /// - /// - protected override string GetMethodCore() - => _method.Method; - - /// - /// TBD. - /// - /// - protected override void SetMethodCore(string method) - => _method = RequestMethod.Parse(method); - - /// - /// TBD. - /// - /// - protected override Uri GetUriCore() - => Uri.ToUri(); - - /// - /// TBD. - /// - /// - protected override void SetUriCore(Uri uri) - => Uri.Reset(uri); + protected override string MethodCore + { + get => _method.Method; + set => _method = RequestMethod.Parse(value); + } /// /// TBD. /// - /// - protected override BinaryContent? GetContentCore() - => _content; + protected override Uri? UriCore + { + get => Uri.ToUri(); + set + { + if (value is null) + { + Uri = new(); + } + else + { + Uri.Reset(value); + } + } + } /// /// TBD. /// - /// - protected override void SetContentCore(BinaryContent? content) - => _content = (RequestContent?)content; + protected override BinaryContent? ContentCore + { + get => _content; + set => _content = (RequestContent?)value; + } /// /// TBD. /// - /// - protected override PipelineRequestHeaders GetHeadersCore() + protected override PipelineRequestHeaders HeadersCore => new AzureCoreMessageHeaders(Headers); #endregion diff --git a/sdk/core/Azure.Core/src/RequestFailedException.cs b/sdk/core/Azure.Core/src/RequestFailedException.cs index 0b179002e162..33fdb99fc3e9 100644 --- a/sdk/core/Azure.Core/src/RequestFailedException.cs +++ b/sdk/core/Azure.Core/src/RequestFailedException.cs @@ -171,11 +171,11 @@ private static async ValueTask CreateExceptionDetailsSyncOrAsync(R { if (async) { - await response.ReadContentAsync().ConfigureAwait(false); + await response.BufferContentAsync().ConfigureAwait(false); } else { - response.ReadContent(); + response.BufferContent(); } parser ??= response.RequestFailedDetailsParser; diff --git a/sdk/core/Azure.Core/src/Response.cs b/sdk/core/Azure.Core/src/Response.cs index c09977ba5213..1c608f0229ac 100644 --- a/sdk/core/Azure.Core/src/Response.cs +++ b/sdk/core/Azure.Core/src/Response.cs @@ -4,8 +4,6 @@ using System; using System.ClientModel.Primitives; using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; @@ -38,10 +36,7 @@ public abstract class Response : PipelineResponse /// /// TBD. /// - /// - /// - [EditorBrowsable(EditorBrowsableState.Never)] - protected override PipelineResponseHeaders GetHeadersCore() + protected override PipelineResponseHeaders HeadersCore => throw new NotImplementedException("Subtypes must implement this method."); /// @@ -56,7 +51,7 @@ public override BinaryData Content { if (ContentStream is null || ContentStream is MemoryStream) { - return ReadContent(); + return BufferContent(); } throw new InvalidOperationException($"The response is not buffered."); @@ -67,16 +62,16 @@ public override BinaryData Content internal RequestFailedDetailsParser? RequestFailedDetailsParser { get; set; } - internal void SetIsError(bool value) => SetIsErrorCore(value); + internal void SetIsError(bool value) => IsErrorCore = value; /// /// TBD. /// - /// - // Azure.Core overrides this only so it can seal it. - [EditorBrowsable(EditorBrowsableState.Never)] - protected sealed override void SetIsErrorCore(bool isError) - => base.SetIsErrorCore(isError); + protected override bool IsErrorCore + { + get => base.IsErrorCore; + set => base.IsErrorCore = value; + } /// /// Returns header value if the header is stored in the collection. If header has multiple values they are going to be joined with a comma. @@ -145,7 +140,7 @@ internal static void DisposeStreamIfNotBuffered(ref Stream? stream) /// /// /// - public override BinaryData ReadContent(CancellationToken cancellationToken = default) + public override BinaryData BufferContent(CancellationToken cancellationToken = default) { // Derived types should provide an implementation that allows caching // to improve performance. @@ -182,7 +177,7 @@ public override BinaryData ReadContent(CancellationToken cancellationToken = def /// /// /// - public override async ValueTask ReadContentAsync(CancellationToken cancellationToken = default) + public override async ValueTask BufferContentAsync(CancellationToken cancellationToken = default) { // Derived types should provide an implementation that allows caching // to improve performance. @@ -242,10 +237,8 @@ public override Stream? ContentStream set => throw new NotSupportedException(DefaultMessage); } - protected override PipelineResponseHeaders GetHeadersCore() - { - throw new NotSupportedException(DefaultMessage); - } + protected override PipelineResponseHeaders HeadersCore + => throw new NotSupportedException(DefaultMessage); public override void Dispose() { @@ -272,12 +265,12 @@ protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(tr throw new NotSupportedException(DefaultMessage); } - public override BinaryData ReadContent(CancellationToken cancellationToken = default) + public override BinaryData BufferContent(CancellationToken cancellationToken = default) { throw new NotSupportedException(DefaultMessage); } - public override ValueTask ReadContentAsync(CancellationToken cancellationToken = default) + public override ValueTask BufferContentAsync(CancellationToken cancellationToken = default) { throw new NotSupportedException(DefaultMessage); } diff --git a/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Response.cs b/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Response.cs index 9253e29395aa..72f7413255a7 100644 --- a/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Response.cs +++ b/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Response.cs @@ -83,12 +83,12 @@ public override BinaryData Content } public override BinaryData BufferContent(CancellationToken cancellationToken = default) - => ReadContentSyncOrAsync(cancellationToken, async: false).EnsureCompleted(); + => BufferContentSyncOrAsync(cancellationToken, async: false).EnsureCompleted(); public override async ValueTask BufferContentAsync(CancellationToken cancellationToken = default) - => await ReadContentSyncOrAsync(cancellationToken, async: true).ConfigureAwait(false); + => await BufferContentSyncOrAsync(cancellationToken, async: true).ConfigureAwait(false); - private async ValueTask ReadContentSyncOrAsync(CancellationToken cancellationToken, bool async) + private async ValueTask BufferContentSyncOrAsync(CancellationToken cancellationToken, bool async) { if (_bufferedContent is not null) { From a525bc2f1c146ebd9c03ae1051c6608ef1a45f3e Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 26 Feb 2024 14:39:09 -0800 Subject: [PATCH 26/47] nits --- sdk/core/Azure.Core/src/Request.cs | 8 ++++---- sdk/core/System.ClientModel/src/System.ClientModel.csproj | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index 02fd5210b4ea..f01e50bfbb77 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -118,7 +118,7 @@ protected override BinaryContent? ContentCore /// TBD. /// protected override PipelineRequestHeaders HeadersCore - => new AzureCoreMessageHeaders(Headers); + => new AzureCoreRequestHeaders(Headers); #endregion @@ -176,16 +176,16 @@ protected internal virtual void SetHeader(string name, string value) protected internal abstract IEnumerable EnumerateHeaders(); /// - /// Backwards adapter to MessageHeaders to implement GetHeadersCore + /// Backwards adapter to RequestHeaders to implement GetHeadersCore. /// - private sealed class AzureCoreMessageHeaders : PipelineRequestHeaders + private sealed class AzureCoreRequestHeaders : PipelineRequestHeaders { /// /// Headers on the Azure.Core.Request type to adapt to. /// private readonly RequestHeaders _headers; - public AzureCoreMessageHeaders(RequestHeaders headers) + public AzureCoreRequestHeaders(RequestHeaders headers) => _headers = headers; public override void Add(string name, string value) diff --git a/sdk/core/System.ClientModel/src/System.ClientModel.csproj b/sdk/core/System.ClientModel/src/System.ClientModel.csproj index 308173cb74df..3d19c5096bdd 100644 --- a/sdk/core/System.ClientModel/src/System.ClientModel.csproj +++ b/sdk/core/System.ClientModel/src/System.ClientModel.csproj @@ -7,7 +7,6 @@ 1.0.0 enable netstandard2.0;net6.0 - $(NoWarn);AZC0001 DotNetPackageIcon.png $(RepoEngPath)/images/$(PackageIcon) From 1dffd97060849af3b241280c51e94ea674d5d2f0 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 26 Feb 2024 17:36:02 -0800 Subject: [PATCH 27/47] pr fb --- .../Pipeline/HttpClientTransport.Adapter.cs | 20 +++---------------- .../Pipeline/HttpPipelineTransport.Adapter.cs | 14 ++----------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index 5cc25119df3a..c0718fc2bd2d 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -33,31 +33,17 @@ protected override PipelineMessage CreateMessageCore() /// protected override void OnSendingRequest(PipelineMessage message, HttpRequestMessage httpRequest) { - if (message is not HttpMessage httpMessage) - { - throw new InvalidOperationException($"Unsupported message type: '{message?.GetType()}'."); - } - + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); HttpClientTransportRequest.AddAzureProperties(httpMessage, httpRequest); - httpMessage.ClearResponse(); } /// protected override void OnReceivedResponse(PipelineMessage message, HttpResponseMessage httpResponse) { - if (message is not HttpMessage httpMessage) - { - throw new InvalidOperationException($"Unsupported message type: '{message?.GetType()}'."); - } - - if (message.Response is not PipelineResponse pipelineResponse) - { - throw new InvalidOperationException($"Unsupported response type: '{message?.GetType()}'."); - } - + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); string clientRequestId = httpMessage.Request.ClientRequestId; - httpMessage.Response = new HttpClientTransportResponse(clientRequestId, pipelineResponse); + httpMessage.Response = new HttpClientTransportResponse(clientRequestId, httpMessage.Response); } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs index 3a2a1ff5a4d1..3098603c1eea 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs @@ -26,24 +26,14 @@ protected override PipelineMessage CreateMessageCore() protected override void ProcessCore(PipelineMessage message) { - HttpMessage httpMessage = AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); _transport.Process(httpMessage); } protected override async ValueTask ProcessCoreAsync(PipelineMessage message) { - HttpMessage httpMessage = AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); await _transport.ProcessAsync(httpMessage).ConfigureAwait(false); } - - private static HttpMessage AssertHttpMessage(PipelineMessage message) - { - if (message is not HttpMessage httpMessage) - { - throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'."); - } - - return httpMessage; - } } } From 9dc085b1b85a0f444588774b7265fb81692788e9 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 26 Feb 2024 18:06:23 -0800 Subject: [PATCH 28/47] nits --- sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index c0718fc2bd2d..112dba07ae49 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; using System.ClientModel.Primitives; using System.Net.Http; From b0c7ce8a784c99d203b72dc96ae0f0f345771401 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 08:43:42 -0800 Subject: [PATCH 29/47] fix --- .../Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index 112dba07ae49..744f4d100658 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.ClientModel.Primitives; using System.Net.Http; @@ -42,7 +43,8 @@ protected override void OnReceivedResponse(PipelineMessage message, HttpResponse { HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); string clientRequestId = httpMessage.Request.ClientRequestId; - httpMessage.Response = new HttpClientTransportResponse(clientRequestId, httpMessage.Response); + PipelineResponse pipelineResponse = message.Response!; + httpMessage.Response = new HttpClientTransportResponse(clientRequestId, pipelineResponse); } } } From fe9839d032a9305ab315541ac67132a2649f4e34 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 08:44:13 -0800 Subject: [PATCH 30/47] nit --- sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index 744f4d100658..7742ce76d86a 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; using System.ClientModel.Primitives; using System.Net.Http; From 5b8bb53d628e8555b53be2f5a6ec20fe21d96de7 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 10:21:29 -0800 Subject: [PATCH 31/47] updates from #42226 --- sdk/core/Azure.Core/src/Request.cs | 46 ++++++++++++------- sdk/core/Azure.Core/src/RequestContent.cs | 54 ++++++++++++----------- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index f01e50bfbb77..ab9862827251 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -11,24 +11,32 @@ namespace Azure.Core { /// - /// Represents an HTTP request. Use or to create an instance. + /// Represents an HTTP request. Use + /// or to create an instance. /// #pragma warning disable AZC0012 // Avoid single word type names public abstract class Request : PipelineRequest #pragma warning restore AZC0012 // Avoid single word type names { - private RequestMethod _method; private RequestUriBuilder? _uriBuilder; private RequestContent? _content; private string? _clientRequestId; + /// + /// Creates a new instance of . + /// + protected Request() + { + MethodCore = RequestMethod.Get.Method; + } + /// /// Gets or sets the request HTTP method. /// public new virtual RequestMethod Method { - get => _method; + get => RequestMethod.Parse(MethodCore); set => MethodCore = value.Method; } @@ -78,16 +86,14 @@ public virtual string ClientRequestId #region Overrides for "Core" methods from the PipelineRequest Template pattern /// - /// TBD. + /// Gets or sets the value of on + /// the base type. /// - protected override string MethodCore - { - get => _method.Method; - set => _method = RequestMethod.Parse(value); - } + protected override string MethodCore { get; set; } /// - /// TBD. + /// Gets or sets the value of on + /// the base type. /// protected override Uri? UriCore { @@ -106,7 +112,8 @@ protected override Uri? UriCore } /// - /// TBD. + /// Gets or sets the value of on + /// the base type. /// protected override BinaryContent? ContentCore { @@ -115,13 +122,15 @@ protected override BinaryContent? ContentCore } /// - /// TBD. + /// Gets the value of on + /// the base type. /// protected override PipelineRequestHeaders HeadersCore - => new AzureCoreRequestHeaders(Headers); + => new RequestHeadersAdapter(Headers); #endregion + #region Abstract header methods /// /// Adds a header value to the header collection. /// @@ -174,18 +183,23 @@ protected internal virtual void SetHeader(string name, string value) /// /// The enumerating in the response. protected internal abstract IEnumerable EnumerateHeaders(); + #endregion /// - /// Backwards adapter to RequestHeaders to implement GetHeadersCore. + /// This adapter adapts the Azure.Core + /// type to the System.ClientModel + /// interface, so that it can can implement the + /// property inherited from + /// . /// - private sealed class AzureCoreRequestHeaders : PipelineRequestHeaders + private sealed class RequestHeadersAdapter : PipelineRequestHeaders { /// /// Headers on the Azure.Core.Request type to adapt to. /// private readonly RequestHeaders _headers; - public AzureCoreRequestHeaders(RequestHeaders headers) + public RequestHeadersAdapter(RequestHeaders headers) => _headers = headers; public override void Add(string name, string value) diff --git a/sdk/core/Azure.Core/src/RequestContent.cs b/sdk/core/Azure.Core/src/RequestContent.cs index 657f5042bb59..12a5878d11fb 100644 --- a/sdk/core/Azure.Core/src/RequestContent.cs +++ b/sdk/core/Azure.Core/src/RequestContent.cs @@ -21,10 +21,9 @@ namespace Azure.Core /// public abstract class RequestContent : BinaryContent { - private static readonly ModelReaderWriterOptions ModelWriteWireOptions = new ModelReaderWriterOptions("W"); - internal const string SerializationRequiresUnreferencedCode = "This method uses reflection-based serialization which is incompatible with trimming. Try using one of the 'Create' overloads that doesn't wrap a serialized version of an object."; private static readonly Encoding s_UTF8NoBomEncoding = new UTF8Encoding(false); + private static readonly ModelReaderWriterOptions ModelWriteWireOptions = new("W"); /// /// Creates an instance of that wraps a . @@ -92,7 +91,7 @@ public abstract class RequestContent : BinaryContent /// The to use. /// An instance of that wraps a a . public static new RequestContent Create(T model, ModelReaderWriterOptions? options = default) where T : IPersistableModel - => new AzureBinaryContent(BinaryContent.Create(model, options ?? ModelWriteWireOptions)); + => new BinaryContentAdapter(BinaryContent.Create(model, options ?? ModelWriteWireOptions)); /// /// Creates an instance of that wraps a serialized version of an object. @@ -152,28 +151,6 @@ public static RequestContent Create(object serializable, JsonPropertyNames prope /// The to use. public static implicit operator RequestContent(DynamicData content) => Create(content); - private sealed class AzureBinaryContent : RequestContent - { - private readonly BinaryContent _content; - - public AzureBinaryContent(BinaryContent content) - { - _content = content; - } - - public override void Dispose() - => _content?.Dispose(); - - public override bool TryComputeLength(out long length) - => _content.TryComputeLength(out length); - - public override void WriteTo(Stream stream, CancellationToken cancellationToken) - => _content.WriteTo(stream, cancellationToken); - - public override async Task WriteToAsync(Stream stream, CancellationToken cancellationToken) - => await _content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); - } - private sealed class StreamContent : RequestContent { private const int CopyToBufferSize = 81920; @@ -356,5 +333,32 @@ public override Task WriteToAsync(Stream stream, CancellationToken cancellation) return Task.CompletedTask; } } + + /// + /// This adapter adapts the System.ClientModel BinaryContent type to + /// the Azure.Core RequestContent interface, so that it can be used as + /// though it were a RequestContent in Azure.Core. + /// + private sealed class BinaryContentAdapter : RequestContent + { + private readonly BinaryContent _content; + + public BinaryContentAdapter(BinaryContent content) + { + _content = content; + } + + public override void Dispose() + => _content?.Dispose(); + + public override bool TryComputeLength(out long length) + => _content.TryComputeLength(out length); + + public override void WriteTo(Stream stream, CancellationToken cancellationToken) + => _content.WriteTo(stream, cancellationToken); + + public override async Task WriteToAsync(Stream stream, CancellationToken cancellationToken) + => await _content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); + } } } From 983f669adfbb8fa8d769d8bd52a1f0f143270226 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 10:42:27 -0800 Subject: [PATCH 32/47] updates --- sdk/core/Azure.Core/src/Request.cs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index ab9862827251..31b664d407df 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -18,19 +18,12 @@ namespace Azure.Core public abstract class Request : PipelineRequest #pragma warning restore AZC0012 // Avoid single word type names { + private string _method = RequestMethod.Get.Method; private RequestUriBuilder? _uriBuilder; private RequestContent? _content; private string? _clientRequestId; - /// - /// Creates a new instance of . - /// - protected Request() - { - MethodCore = RequestMethod.Get.Method; - } - /// /// Gets or sets the request HTTP method. /// @@ -49,7 +42,6 @@ protected Request() set { Argument.AssertNotNull(value, nameof(value)); - _uriBuilder = value; } } @@ -89,7 +81,11 @@ public virtual string ClientRequestId /// Gets or sets the value of on /// the base type. /// - protected override string MethodCore { get; set; } + protected override string MethodCore + { + get => _method; + set => _method = value; + } /// /// Gets or sets the value of on @@ -97,7 +93,16 @@ public virtual string ClientRequestId /// protected override Uri? UriCore { + // The _uriBuilder field on this type is the source of truth for + // the type's Uri implementation. Accessing it through the Uri + // property allows us to reuse the lazy-instantation implemented + // there. get => Uri.ToUri(); + + // This setter effectively adapts the BCL Uri type to the Azure.Core + // RequestUriBuilder interface, in that the only way + // RequestUriBuilder provides to fully reset the Uri (i.e. from null) + // is to create a new instance of the builder. set { if (value is null) From 78f57c8ac72356a22778c1d01786d61eb7d163b6 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 10:53:36 -0800 Subject: [PATCH 33/47] fix merge --- .../src/Pipeline/HttpWebRequestTransport.cs | 279 +----------------- 1 file changed, 3 insertions(+), 276 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs index f3153bbe9011..9cc77f89e123 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpWebRequestTransport.cs @@ -2,14 +2,7 @@ // Licensed under the MIT License. using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; using System.Net; -using System.Net.Http.Headers; -using System.Security.Cryptography.X509Certificates; -using System.Threading; using System.Threading.Tasks; namespace Azure.Core.Pipeline @@ -18,7 +11,7 @@ namespace Azure.Core.Pipeline /// /// The based implementation. /// - internal class HttpWebRequestTransport : HttpPipelineTransport + internal partial class HttpWebRequestTransport : HttpPipelineTransport { private readonly Action _configureRequest; public static readonly HttpWebRequestTransport Shared = new HttpWebRequestTransport(); @@ -104,7 +97,7 @@ private async ValueTask ProcessSyncOrAsync(HttpMessage message, bool async) webResponse = exception.Response; } - message.Response = new HttpWebTransportResponse(message.Request.ClientRequestId, (HttpWebResponse)webResponse); + message.Response = new HttpWebRequestTransportResponse(message.Request.ClientRequestId, (HttpWebResponse)webResponse); } // ObjectDisposedException might be thrown if the request is aborted during the content upload via SSL catch (ObjectDisposedException) when (message.CancellationToken.IsCancellationRequested) @@ -119,275 +112,9 @@ private async ValueTask ProcessSyncOrAsync(HttpMessage message, bool async) } } - private HttpWebRequest CreateRequest(Request messageRequest) - { - var request = WebRequest.CreateHttp(messageRequest.Uri.ToUri()); - - // Timeouts are handled by the pipeline - request.Timeout = Timeout.Infinite; - request.ReadWriteTimeout = Timeout.Infinite; - - // Redirect is handled by the pipeline - request.AllowAutoRedirect = false; - - // Don't disable the default proxy when there is no environment proxy configured - if (_environmentProxy != null) - { - request.Proxy = _environmentProxy; - } - - request.ServicePoint.Expect100Continue = false; - - _configureRequest(request); - - request.Method = messageRequest.Method.Method; - foreach (var messageRequestHeader in messageRequest.Headers) - { - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.ContentLength, StringComparison.OrdinalIgnoreCase)) - { - request.ContentLength = long.Parse(messageRequestHeader.Value, CultureInfo.InvariantCulture); - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.Host, StringComparison.OrdinalIgnoreCase)) - { - request.Host = messageRequestHeader.Value; - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.Date, StringComparison.OrdinalIgnoreCase)) - { - request.Date = DateTime.Parse(messageRequestHeader.Value, CultureInfo.InvariantCulture); - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.ContentType, StringComparison.OrdinalIgnoreCase)) - { - request.ContentType = messageRequestHeader.Value; - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.UserAgent, StringComparison.OrdinalIgnoreCase)) - { - request.UserAgent = messageRequestHeader.Value; - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.Accept, StringComparison.OrdinalIgnoreCase)) - { - request.Accept = messageRequestHeader.Value; - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.Referer, StringComparison.OrdinalIgnoreCase)) - { - request.Referer = messageRequestHeader.Value; - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.IfModifiedSince, StringComparison.OrdinalIgnoreCase)) - { - request.IfModifiedSince = DateTime.Parse(messageRequestHeader.Value, CultureInfo.InvariantCulture); - continue; - } - - if (string.Equals(messageRequestHeader.Name, "Expect", StringComparison.OrdinalIgnoreCase)) - { - if (messageRequestHeader.Value == "100-continue") - { - request.ServicePoint.Expect100Continue = true; - } - else - { - request.Expect = messageRequestHeader.Value; - } - continue; - } - - if (string.Equals(messageRequestHeader.Name, "Transfer-Encoding", StringComparison.OrdinalIgnoreCase)) - { - request.TransferEncoding = messageRequestHeader.Value; - continue; - } - - if (string.Equals(messageRequestHeader.Name, HttpHeader.Names.Range, StringComparison.OrdinalIgnoreCase)) - { - var value = RangeHeaderValue.Parse(messageRequestHeader.Value); - if (value.Unit != "bytes") - { - throw new InvalidOperationException("Only ranges with bytes unit supported."); - } - - foreach (var rangeItem in value.Ranges) - { - if (rangeItem.From == null) - { - throw new InvalidOperationException("Only ranges with Offset supported."); - } - - if (rangeItem.To == null) - { - request.AddRange(rangeItem.From.Value); - } - else - { - request.AddRange(rangeItem.From.Value, rangeItem.To.Value); - } - } - continue; - } - - request.Headers.Add(messageRequestHeader.Name, messageRequestHeader.Value); - } - - if (request.ContentLength == -1 && - messageRequest.Content != null && - messageRequest.Content.TryComputeLength(out var length)) - { - request.ContentLength = length; - } - - if (request.ContentLength != -1) - { - // disable buffering when the content length is known - // as the content stream is re-playable and we don't want to allocate extra buffers - request.AllowWriteStreamBuffering = false; - } - return request; - } - /// public override Request CreateRequest() - { - return new HttpWebTransportRequest(); - } - - private sealed class HttpWebTransportRequest : Request - { - public HttpWebTransportRequest() - { - Method = RequestMethod.Get; - } - - private readonly DictionaryHeaders _headers = new(); - - protected internal override void SetHeader(string name, string value) => _headers.SetHeader(name, value); - - protected internal override void AddHeader(string name, string value) => _headers.AddHeader(name, value); - - protected internal override bool TryGetHeader(string name, out string value) => _headers.TryGetHeader(name, out value); - - protected internal override bool TryGetHeaderValues(string name, out IEnumerable values) => _headers.TryGetHeaderValues(name, out values); - - protected internal override bool ContainsHeader(string name) => _headers.TryGetHeaderValues(name, out _); - - protected internal override bool RemoveHeader(string name) => _headers.RemoveHeader(name); - - protected internal override IEnumerable EnumerateHeaders() => _headers.EnumerateHeaders(); - - public override RequestContent? Content { get; set; } - - public override void Dispose() - { - var content = Content; - if (content != null) - { - Content = null; - content.Dispose(); - } - } - } - - private sealed class HttpWebTransportResponse : Response - { - private readonly HttpWebResponse _webResponse; - private Stream? _contentStream; - private Stream? _originalContentStream; - - public HttpWebTransportResponse(string clientRequestId, HttpWebResponse webResponse) - { - _webResponse = webResponse; - _originalContentStream = _webResponse.GetResponseStream(); - _contentStream = _originalContentStream; - ClientRequestId = clientRequestId; - } - - public override int Status => (int)_webResponse.StatusCode; - - public override string ReasonPhrase => _webResponse.StatusDescription; - - public override Stream? ContentStream - { - get => _contentStream; - set - { - // Make sure we don't dispose the content if the stream was replaced - _originalContentStream = null; - - _contentStream = value; - } - } - - public override string ClientRequestId { get; set; } - - public override void Dispose() - { - // In the case of failed response the content stream would be - // pre-buffered subclass of MemoryStream - // keep it alive because the ResponseBodyPolicy won't re-buffer it - DisposeStreamIfNotBuffered(ref _originalContentStream); - DisposeStreamIfNotBuffered(ref _contentStream); - } - - protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) - { - value = _webResponse.Headers.Get(name); - return value != null; - } - - protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) - { - values = _webResponse.Headers.GetValues(name); - return values != null; - } - - protected internal override bool ContainsHeader(string name) - { - return _webResponse.Headers.Get(name) != null; - } - - protected internal override IEnumerable EnumerateHeaders() - { - foreach (var key in _webResponse.Headers.AllKeys) - { - yield return new HttpHeader(key, _webResponse.Headers.Get(key)); - } - } - } - - private static void ApplyOptionsToRequest(HttpWebRequest request, HttpPipelineTransportOptions options) - { - if (options == null) - { - return; - } - - // ServerCertificateCustomValidationCallback - if (options.ServerCertificateCustomValidationCallback != null) - { - request.ServerCertificateValidationCallback = - (request, certificate, x509Chain, sslPolicyErrors) => options.ServerCertificateCustomValidationCallback( - new ServerCertificateCustomValidationArgs( - new X509Certificate2(certificate), - x509Chain, - sslPolicyErrors)); - } - // Set ClientCertificates - foreach (var cert in options.ClientCertificates) - { - request.ClientCertificates.Add(cert); - } - } + => new HttpWebRequestTransportRequest(); } #endif } From 73fca667a608462bd5b3f2c6d516e231725cce8c Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 11:00:25 -0800 Subject: [PATCH 34/47] post-merge updates --- .../Internal/AzureBaseBuffersExtensions.cs | 2 ++ .../Azure.Core/src/Pipeline/HttpPipeline.cs | 2 +- .../src/Pipeline/HttpPipelineBuilder.cs | 24 ++++++++++--------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs b/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs index cede9eade4c3..bdaf6d160194 100644 --- a/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs +++ b/sdk/core/Azure.Core/src/Internal/AzureBaseBuffersExtensions.cs @@ -109,6 +109,7 @@ public static async Task CopyToAsync(this Stream source, Stream destination, Can } finally { + await destination.FlushAsync(cancellationToken).ConfigureAwait(false); ArrayPool.Shared.Return(buffer); } } @@ -128,6 +129,7 @@ public static void CopyTo(this Stream source, Stream destination, CancellationTo } finally { + destination.Flush(); ArrayPool.Shared.Return(buffer); } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs index a8e24702f5ff..1df9052396e0 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs @@ -55,7 +55,7 @@ public HttpPipeline(HttpPipelineTransport transport, HttpPipelinePolicy[]? polic policies ??= Array.Empty(); - var all = new HttpPipelinePolicy[policies.Length + 1]; + HttpPipelinePolicy[] all = new HttpPipelinePolicy[policies.Length + 1]; all[policies.Length] = new HttpPipelineTransportPolicy(_transport, ClientDiagnostics.CreateMessageSanitizer(new DiagnosticsOptions())); policies.CopyTo(all, 0); diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs index d218be0c7b82..afba624f7d17 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineBuilder.cs @@ -13,10 +13,12 @@ namespace Azure.Core.Pipeline /// public static class HttpPipelineBuilder { + private static int DefaultPolicyCount = 7; + /// - /// Creates an instance of populated with default policies, customer provided policies from and client provided per call policies. + /// Creates an instance of populated with default policies, user-provided policies from and client provided per call policies. /// - /// The customer provided client options object. + /// The user-provided client options object. /// Client provided per-retry policies. /// A new instance of public static HttpPipeline Build(ClientOptions options, params HttpPipelinePolicy[] perRetryPolicies) @@ -25,9 +27,9 @@ public static HttpPipeline Build(ClientOptions options, params HttpPipelinePolic } /// - /// Creates an instance of populated with default policies, customer provided policies from and client provided per call policies. + /// Creates an instance of populated with default policies, user-provided policies from and client provided per call policies. /// - /// The customer provided client options object. + /// The user-provided client options object. /// Client provided per-call policies. /// Client provided per-retry policies. /// The client provided response classifier. @@ -47,12 +49,12 @@ public static HttpPipeline Build( } /// - /// Creates an instance of populated with default policies, customer provided policies from , client provided per call policies, and the supplied . + /// Creates an instance of populated with default policies, user-provided policies from , client provided per call policies, and the supplied . /// - /// The customer provided client options object. + /// The user-provided client options object. /// Client provided per-call policies. /// Client provided per-retry policies. - /// The customer provided transport options which will be applied to the default transport. Note: If a custom transport has been supplied via the , these will be ignored. + /// The user-provided transport options which will be applied to the default transport. Note: If a custom transport has been supplied via the , these will be ignored. /// The client provided response classifier. /// A new instance of public static DisposableHttpPipeline Build(ClientOptions options, HttpPipelinePolicy[] perCallPolicies, HttpPipelinePolicy[] perRetryPolicies, HttpPipelineTransportOptions transportOptions, ResponseClassifier? responseClassifier) @@ -67,7 +69,7 @@ public static DisposableHttpPipeline Build(ClientOptions options, HttpPipelinePo } /// - /// Creates an instance of populated with default policies, customer provided policies from and client provided per call policies. + /// Creates an instance of populated with default policies, user-provided policies from and client provided per call policies. /// /// The configuration options used to build the /// A new instance of @@ -78,10 +80,10 @@ public static HttpPipeline Build(HttpPipelineOptions options) } /// - /// Creates an instance of populated with default policies, customer provided policies from , client provided per call policies, and the supplied . + /// Creates an instance of populated with default policies, user-provided policies from , client provided per call policies, and the supplied . /// /// The configuration options used to build the - /// The customer provided transport options which will be applied to the default transport. Note: If a custom transport has been supplied via the , these will be ignored. + /// The user-provided transport options which will be applied to the default transport. Note: If a custom transport has been supplied via the , these will be ignored. /// A new instance of public static DisposableHttpPipeline Build(HttpPipelineOptions options, HttpPipelineTransportOptions transportOptions) { @@ -97,7 +99,7 @@ internal static (ResponseClassifier Classifier, HttpPipelineTransport Transport, Argument.AssertNotNull(buildOptions.PerCallPolicies, nameof(buildOptions.PerCallPolicies)); Argument.AssertNotNull(buildOptions.PerRetryPolicies, nameof(buildOptions.PerRetryPolicies)); - var policies = new List(7 + + var policies = new List(DefaultPolicyCount + (buildOptions.ClientOptions.Policies?.Count ?? 0) + buildOptions.PerCallPolicies.Count + buildOptions.PerRetryPolicies.Count); From 3f9f5940089bd1c823f022f4ebbc43415581c2a2 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 11:33:21 -0800 Subject: [PATCH 35/47] updates --- .../Pipeline/HttpClientTransport.Request.cs | 19 +++++++++-- sdk/core/Azure.Core/src/Request.cs | 32 +++++++------------ 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs index 682e91649632..0780ed49d1f2 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs @@ -26,6 +26,7 @@ private sealed class HttpClientTransportRequest : Request // Request or PipelineRequest. private readonly PipelineRequest _pipelineRequest; + private string? _clientRequestId; public HttpClientTransportRequest(PipelineRequest request) { @@ -33,9 +34,22 @@ public HttpClientTransportRequest(PipelineRequest request) // Initialize duplicated properties on base type from adapted request. base.MethodCore = request.Method; + base.ContentCore = request.Content; - // Uri and Content are initialized to null in constructor - // so don't need to be set here. + if (request.Uri is not null) + { + base.UriCore = request.Uri; + } + } + + public override string ClientRequestId + { + get => _clientRequestId ??= Guid.NewGuid().ToString(); + set + { + Argument.AssertNotNull(value, nameof(value)); + _clientRequestId = value; + } } #region Adapt PipelineResponse to inherit functional implementation from ClientModel @@ -50,6 +64,7 @@ protected override string MethodCore _pipelineRequest.Method = value; } } + protected override Uri? UriCore { get diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index 31b664d407df..e14c0a443fe8 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -18,21 +18,10 @@ namespace Azure.Core public abstract class Request : PipelineRequest #pragma warning restore AZC0012 // Avoid single word type names { - private string _method = RequestMethod.Get.Method; private RequestUriBuilder? _uriBuilder; + private string _method = RequestMethod.Get.Method; private RequestContent? _content; - private string? _clientRequestId; - - /// - /// Gets or sets the request HTTP method. - /// - public new virtual RequestMethod Method - { - get => RequestMethod.Parse(MethodCore); - set => MethodCore = value.Method; - } - /// /// Gets or sets and instance of used to create the Uri. /// @@ -46,6 +35,15 @@ public abstract class Request : PipelineRequest } } + /// + /// Gets or sets the request HTTP method. + /// + public new virtual RequestMethod Method + { + get => RequestMethod.Parse(MethodCore); + set => MethodCore = value.Method; + } + /// /// Gets or sets the request content. /// @@ -58,15 +56,7 @@ public abstract class Request : PipelineRequest /// /// Gets or sets the client request id that was sent to the server as x-ms-client-request-id headers. /// - public virtual string ClientRequestId - { - get => _clientRequestId ??= Guid.NewGuid().ToString(); - set - { - Argument.AssertNotNull(value, nameof(value)); - _clientRequestId = value; - } - } + public abstract string ClientRequestId { get; set; } /// /// Gets the request HTTP headers. From d9a2808366ca86dea30105c9b6edd59bb57f38dd Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 11:55:11 -0800 Subject: [PATCH 36/47] export API --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 2 +- sdk/core/Azure.Core/api/Azure.Core.net472.cs | 2 +- sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 2 +- sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index b060f6118980..d73eba362112 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -541,7 +541,7 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public virtual string ClientRequestId { get { throw null; } set { } } + public abstract string ClientRequestId { get; set; } public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } public new Azure.Core.RequestHeaders Headers { get { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index b060f6118980..d73eba362112 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -541,7 +541,7 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public virtual string ClientRequestId { get { throw null; } set { } } + public abstract string ClientRequestId { get; set; } public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } public new Azure.Core.RequestHeaders Headers { get { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index a0e29c87f5a0..9cc252d8e066 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -541,7 +541,7 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public virtual string ClientRequestId { get { throw null; } set { } } + public abstract string ClientRequestId { get; set; } public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } public new Azure.Core.RequestHeaders Headers { get { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index b060f6118980..d73eba362112 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -541,7 +541,7 @@ void System.ClientModel.Primitives.IJsonModel.Write(System.Text.Json.Utf public abstract partial class Request : System.ClientModel.Primitives.PipelineRequest { protected Request() { } - public virtual string ClientRequestId { get { throw null; } set { } } + public abstract string ClientRequestId { get; set; } public virtual new Azure.Core.RequestContent? Content { get { throw null; } set { } } protected override System.ClientModel.BinaryContent? ContentCore { get { throw null; } set { } } public new Azure.Core.RequestHeaders Headers { get { throw null; } } From 4c1cd7a32149d3dad86dd4a8b4373b7fa6d35087 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 16:50:30 -0800 Subject: [PATCH 37/47] updates from Request PR --- sdk/core/Azure.Core/src/Request.cs | 7 +- sdk/core/Azure.Core/src/RequestContent.cs | 5 +- .../tests/HttpPipelineRequestContentTests.cs | 79 +++++++++++++++++++ sdk/core/Azure.Core/tests/RequestTests.cs | 51 ++++++++++++ 4 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 sdk/core/Azure.Core/tests/RequestTests.cs diff --git a/sdk/core/Azure.Core/src/Request.cs b/sdk/core/Azure.Core/src/Request.cs index e14c0a443fe8..448a8da5ec6f 100644 --- a/sdk/core/Azure.Core/src/Request.cs +++ b/sdk/core/Azure.Core/src/Request.cs @@ -113,7 +113,12 @@ protected override Uri? UriCore protected override BinaryContent? ContentCore { get => _content; - set => _content = (RequestContent?)value; + set => _content = value switch + { + RequestContent content => content, + BinaryContent => new RequestContent.BinaryContentAdapter(value), + null => null, + }; } /// diff --git a/sdk/core/Azure.Core/src/RequestContent.cs b/sdk/core/Azure.Core/src/RequestContent.cs index 12a5878d11fb..4d275bb23a94 100644 --- a/sdk/core/Azure.Core/src/RequestContent.cs +++ b/sdk/core/Azure.Core/src/RequestContent.cs @@ -23,7 +23,6 @@ public abstract class RequestContent : BinaryContent { internal const string SerializationRequiresUnreferencedCode = "This method uses reflection-based serialization which is incompatible with trimming. Try using one of the 'Create' overloads that doesn't wrap a serialized version of an object."; private static readonly Encoding s_UTF8NoBomEncoding = new UTF8Encoding(false); - private static readonly ModelReaderWriterOptions ModelWriteWireOptions = new("W"); /// /// Creates an instance of that wraps a . @@ -91,7 +90,7 @@ public abstract class RequestContent : BinaryContent /// The to use. /// An instance of that wraps a a . public static new RequestContent Create(T model, ModelReaderWriterOptions? options = default) where T : IPersistableModel - => new BinaryContentAdapter(BinaryContent.Create(model, options ?? ModelWriteWireOptions)); + => new BinaryContentAdapter(BinaryContent.Create(model, options)); /// /// Creates an instance of that wraps a serialized version of an object. @@ -339,7 +338,7 @@ public override Task WriteToAsync(Stream stream, CancellationToken cancellation) /// the Azure.Core RequestContent interface, so that it can be used as /// though it were a RequestContent in Azure.Core. /// - private sealed class BinaryContentAdapter : RequestContent + internal sealed class BinaryContentAdapter : RequestContent { private readonly BinaryContent _content; diff --git a/sdk/core/Azure.Core/tests/HttpPipelineRequestContentTests.cs b/sdk/core/Azure.Core/tests/HttpPipelineRequestContentTests.cs index 6d58550f1a3f..f31f6c86d484 100644 --- a/sdk/core/Azure.Core/tests/HttpPipelineRequestContentTests.cs +++ b/sdk/core/Azure.Core/tests/HttpPipelineRequestContentTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Collections.Generic; using System.IO; using System.Text; @@ -135,6 +136,20 @@ public void DictionaryContent() Assert.AreEqual(expected, reader.ReadToEnd()); } + [Test] + public void JsonModelContent() + { + MockJsonModel model = new(404, "abcde"); + using RequestContent content = RequestContent.Create(model, ModelReaderWriterOptions.Json); + + MemoryStream destination = new(); + content.WriteTo(destination, default); + + destination.Position = 0; + + Assert.AreEqual(model.Utf8BytesValue, destination.ToArray()); + } + [Test] public void DynamicDataContent() { @@ -196,5 +211,69 @@ public void CamelCaseContent() CollectionAssert.AreEqual(expected.ToArray(), destination.ToArray()); } + + #region Helpers + + private class MockJsonModel : IJsonModel + { + public int IntValue { get; set; } + + public string StringValue { get; set; } + + public byte[] Utf8BytesValue { get; } + + public MockJsonModel(int intValue, string stringValue) + { + IntValue = intValue; + StringValue = stringValue; + + dynamic json = BinaryData.FromString("{}").ToDynamicFromJson(JsonPropertyNames.CamelCase); + json.IntValue = IntValue; + json.StringValue = StringValue; + + MemoryStream stream = new(); + using Utf8JsonWriter writer = new Utf8JsonWriter(stream); + + writer.WriteStartObject(); + writer.WriteNumber("IntValue", IntValue); + writer.WriteString("StringValue", StringValue); + writer.WriteEndObject(); + + writer.Flush(); + Utf8BytesValue = stream.ToArray(); + } + + MockJsonModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) + { + dynamic json = data.ToDynamicFromJson(JsonPropertyNames.CamelCase); + return new MockJsonModel(json.IntValue, json.StringValue); + } + + MockJsonModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) + { + using JsonDocument doc = JsonDocument.ParseValue(ref reader); + int intValue = doc.RootElement.GetProperty("IntValue").GetInt32(); + string stringValue = doc.RootElement.GetProperty("StringValue").GetString()!; + return new MockJsonModel(intValue, stringValue); + } + + string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) + => "J"; + + BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) + { + return BinaryData.FromBytes(Utf8BytesValue); + } + + void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options) + { + writer.WriteStartObject(); + writer.WriteNumber("IntValue", IntValue); + writer.WriteString("StringValue", StringValue); + writer.WriteEndObject(); + } + } + + #endregion } } diff --git a/sdk/core/Azure.Core/tests/RequestTests.cs b/sdk/core/Azure.Core/tests/RequestTests.cs new file mode 100644 index 000000000000..3ddd5ef101b8 --- /dev/null +++ b/sdk/core/Azure.Core/tests/RequestTests.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ClientModel; +using System.ClientModel.Primitives; +using System.IO; +using Azure.Core.TestFramework; +using NUnit.Framework; + +namespace Azure.Core.Tests; + +internal class RequestTests +{ + [Test] + public void UriCoreSetsUri() + { + Uri mockUri = new Uri("https://www.example.com"); + + MockRequest request = new MockRequest(); + PipelineRequest pipelineRequest = request; + pipelineRequest.Uri = mockUri; + + Assert.AreEqual(mockUri, request.Uri.ToUri()); + } + + [Test] + public void MethodCoreSetsMethod() + { + MockRequest request = new MockRequest(); + PipelineRequest pipelineRequest = request; + pipelineRequest.Method = "POST"; + + Assert.AreEqual(RequestMethod.Post, request.Method); + } + + [Test] + public void ContentCoreSetsContent() + { + BinaryData mockContent = BinaryData.FromString("Mock content"); + + MockRequest request = new MockRequest(); + PipelineRequest pipelineRequest = request; + pipelineRequest.Content = BinaryContent.Create(mockContent); + + MemoryStream destination = new(); + request.Content.WriteTo(destination); + + Assert.AreEqual(mockContent.ToArray(), destination.ToArray()); + } +} From 5de4f0dc8f9f4415ac347d93e46f080cefcb0829 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Tue, 27 Feb 2024 17:54:37 -0800 Subject: [PATCH 38/47] Updates from #42234 --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 1 - sdk/core/Azure.Core/api/Azure.Core.net472.cs | 1 - sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 1 - .../api/Azure.Core.netstandard2.0.cs | 1 - .../Azure.Core/src/NullableResponseOfT.cs | 121 +++++++-- sdk/core/Azure.Core/src/Response.cs | 256 ++++++++---------- sdk/core/Azure.Core/src/ResponseOfT.cs | 20 +- .../tests/NullableResponseOfTTests.cs | 16 +- 8 files changed, 247 insertions(+), 170 deletions(-) diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index d73eba362112..cf12221fe86e 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -244,7 +244,6 @@ protected Response() { } public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } - protected override bool IsErrorCore { get { throw null; } set { } } public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index d73eba362112..cf12221fe86e 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -244,7 +244,6 @@ protected Response() { } public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } - protected override bool IsErrorCore { get { throw null; } set { } } public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index 9cc252d8e066..e4daa01280ac 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -244,7 +244,6 @@ protected Response() { } public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } - protected override bool IsErrorCore { get { throw null; } set { } } public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index d73eba362112..cf12221fe86e 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -244,7 +244,6 @@ protected Response() { } public override System.BinaryData Content { get { throw null; } } public virtual new Azure.Core.ResponseHeaders Headers { get { throw null; } } protected override System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get { throw null; } } - protected override bool IsErrorCore { get { throw null; } set { } } public override System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.ValueTask BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } protected internal abstract bool ContainsHeader(string name); diff --git a/sdk/core/Azure.Core/src/NullableResponseOfT.cs b/sdk/core/Azure.Core/src/NullableResponseOfT.cs index 1ddad9f45289..dca69945143a 100644 --- a/sdk/core/Azure.Core/src/NullableResponseOfT.cs +++ b/sdk/core/Azure.Core/src/NullableResponseOfT.cs @@ -1,8 +1,16 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.ClientModel; +using System.ClientModel.Primitives; +using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; namespace Azure { @@ -16,45 +24,53 @@ public abstract class NullableResponse : ClientResult { private const string NoValue = ""; - private readonly T? _value; - - internal static Response DefaultResponse = new Response.AzureCoreDefaultResponse(); + // This property is used to enable passing a value to the base type + // that validates Response is not null. We don't expect this to be + // used, so it is instantiated lazily. + private static DefaultResponse? _defaultRawResponse; + private static DefaultResponse DefaultRawResponse + => _defaultRawResponse ??= new(); /// - /// TBD. + /// Creates an instance of with no + /// value or . It is not intended for this + /// constructor to be called, as it will create an instance of + /// with a null , + /// which is not the intended usage of this type. /// [EditorBrowsable(EditorBrowsableState.Never)] - protected NullableResponse() : base(default, DefaultResponse) + protected NullableResponse() : base(default, DefaultRawResponse) { // Added for back-compat with GA APIs. Any type that derives from - // Response must provide an implementation for GetRawResponse that - // replaces DefaultResponse with the Response populated on HttpMessage - // during the call to pipeline.Send. - - _value = default; + // NullableResponse must provide an implementation for + // GetRawResponse that replaces DefaultResponse with the Response + // populated on HttpMessage during the call to pipeline.Send. } /// - /// TBD. + /// Creates an instance of from the + /// provided and . /// - /// - /// + /// The value to return from + /// on the created instance. + /// The to return from + /// on the created instance. protected NullableResponse(T? value, Response response) - : base(value,ReplaceWithDefaultIfNull(response)) + : base(value, ReplaceWithDefaultIfNull(response)) { - _value = value; } /// /// Gets a value indicating whether the current instance has a non-null value. /// - public virtual bool HasValue => _value != null; + public virtual bool HasValue => Value != null; /// /// Returns the HTTP response returned by the service. /// /// The HTTP response returned by the service. - public new virtual Response GetRawResponse() => (Response)base.GetRawResponse(); + public new virtual Response GetRawResponse() + => (Response)base.GetRawResponse(); /// [EditorBrowsable(EditorBrowsableState.Never)] @@ -69,6 +85,75 @@ public override string ToString() => $"Status: {GetRawResponse()?.Status}, Value: {(HasValue ? Value : NoValue)}"; private static Response ReplaceWithDefaultIfNull(Response? response) - => response ?? DefaultResponse; + => response ?? DefaultRawResponse; + + // This nested type enables back-compatibility with the protected + // parameterless contructor on NullableResponse. It implements + // Response so that a non-null PipelineResponse can be passed to the + // base ClientResult constructor to prevent an ArgumentNullException + // from being thrown. Any caller that accesses this Response via + // GetRawResponse on the NullableResponse instance will get an + // exception saying that the derived type has been implemented + // incorrectly. + private class DefaultResponse : Response + { + private readonly string ExceptionMessage = "Types derived from abstract NullableResponse or Response must provide an implementation of the virtual GetRawResponse method that returns a non-null Response value."; + + public override string ClientRequestId + { + get => throw new NotSupportedException(ExceptionMessage); + set => throw new NotSupportedException(ExceptionMessage); + } + + public override int Status + => throw new NotSupportedException(ExceptionMessage); + + public override string ReasonPhrase + => throw new NotSupportedException(ExceptionMessage); + + public override Stream? ContentStream + { + get => throw new NotSupportedException(ExceptionMessage); + set => throw new NotSupportedException(ExceptionMessage); + } + + protected override PipelineResponseHeaders HeadersCore + => throw new NotSupportedException(ExceptionMessage); + + public override void Dispose() + { + throw new NotSupportedException(ExceptionMessage); + } + + protected internal override bool ContainsHeader(string name) + { + throw new NotSupportedException(ExceptionMessage); + } + + protected internal override IEnumerable EnumerateHeaders() + { + throw new NotSupportedException(ExceptionMessage); + } + + protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) + { + throw new NotSupportedException(ExceptionMessage); + } + + protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) + { + throw new NotSupportedException(ExceptionMessage); + } + + public override BinaryData BufferContent(CancellationToken cancellationToken = default) + { + throw new NotSupportedException(ExceptionMessage); + } + + public override ValueTask BufferContentAsync(CancellationToken cancellationToken = default) + { + throw new NotSupportedException(ExceptionMessage); + } + } } } diff --git a/sdk/core/Azure.Core/src/Response.cs b/sdk/core/Azure.Core/src/Response.cs index 1c608f0229ac..fb0e08b22c0e 100644 --- a/sdk/core/Azure.Core/src/Response.cs +++ b/sdk/core/Azure.Core/src/Response.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Azure.Core; using Azure.Core.Buffers; +using Azure.Core.Pipeline; namespace Azure { @@ -33,12 +34,6 @@ public abstract class Response : PipelineResponse /// public new virtual ResponseHeaders Headers => new ResponseHeaders(this); - /// - /// TBD. - /// - protected override PipelineResponseHeaders HeadersCore - => throw new NotImplementedException("Subtypes must implement this method."); - /// /// Gets the contents of HTTP response, if it is available. /// @@ -58,20 +53,20 @@ public override BinaryData Content } } + /// + /// Gets the value of on + /// the base type. + /// + protected override PipelineResponseHeaders HeadersCore + => new ResponseHeadersAdapter(Headers); + + internal void SetIsError(bool value) => IsErrorCore = value; + internal HttpMessageSanitizer Sanitizer { get; set; } = HttpMessageSanitizer.Default; internal RequestFailedDetailsParser? RequestFailedDetailsParser { get; set; } - internal void SetIsError(bool value) => IsErrorCore = value; - - /// - /// TBD. - /// - protected override bool IsErrorCore - { - get => base.IsErrorCore; - set => base.IsErrorCore = value; - } + #region Abstract header methods /// /// Returns header value if the header is stored in the collection. If header has multiple values they are going to be joined with a comma. @@ -102,48 +97,38 @@ protected override bool IsErrorCore /// The enumerating in the response. protected internal abstract IEnumerable EnumerateHeaders(); - /// - /// Creates a new instance of with the provided value and HTTP response. - /// - /// The type of the value. - /// The value. - /// The HTTP response. - /// A new instance of with the provided value and HTTP response. - public static Response FromValue(T value, Response response) - => new AzureCoreResponse(value, response); + #endregion + + #region BufferContent implementation + + /// + public override BinaryData BufferContent(CancellationToken cancellationToken = default) + => BufferContentSyncOrAsync(cancellationToken, async: false).EnsureCompleted(); + + /// + public override async ValueTask BufferContentAsync(CancellationToken cancellationToken = default) + => await BufferContentSyncOrAsync(cancellationToken, async: true).ConfigureAwait(false); /// - /// Returns the string representation of this . + /// Provide a default implementation of the + /// method inherited from + /// . This is used by any types derived + /// from that don't override the BufferContent + /// methods. It is intended that any high-performance implementation + /// will override these methods instead of using the default + /// implementation. /// - /// The string representation of this - public override string ToString() + private async ValueTask BufferContentSyncOrAsync(CancellationToken cancellationToken, bool async) { - return $"Status: {Status}, ReasonPhrase: {ReasonPhrase}"; - } + // We can tell the content has been buffered and not overwritten by + // a call to the abstract ContentStream setter if ContentStream is + // an instance our private BufferContentStream type. - internal static void DisposeStreamIfNotBuffered(ref Stream? stream) - { - // We want to keep the ContentStream readable - // even after the response is disposed but only if it's a - // buffered memory stream otherwise we can leave a network - // connection hanging open - if (stream is not MemoryStream) + if (ContentStream is BufferedContentStream bufferedContent) { - stream?.Dispose(); - stream = null; + return bufferedContent.Content; } - } - /// - /// TBD. - /// - /// - /// - /// - public override BinaryData BufferContent(CancellationToken cancellationToken = default) - { - // Derived types should provide an implementation that allows caching - // to improve performance. if (ContentStream is null) { return s_EmptyBinaryData; @@ -151,130 +136,125 @@ public override BinaryData BufferContent(CancellationToken cancellationToken = d if (ContentStream is MemoryStream memoryStream) { - return memoryStream.TryGetBuffer(out ArraySegment segment) ? - new BinaryData(segment.AsMemory()) : - new BinaryData(memoryStream.ToArray()); + return BufferedContentStream.FromBuffer(memoryStream); } BufferedContentStream bufferStream = new(); - Stream? contentStream = ContentStream; - contentStream.CopyTo(bufferStream, cancellationToken); - contentStream.Dispose(); - bufferStream.Position = 0; - ContentStream = bufferStream; + if (async) + { + await contentStream.CopyToAsync(bufferStream, cancellationToken).ConfigureAwait(false); +#if NET6_0_OR_GREATER + await contentStream.DisposeAsync().ConfigureAwait(false); +#else + contentStream.Dispose(); +#endif + } + else + { + contentStream.CopyTo(bufferStream, cancellationToken); + contentStream.Dispose(); + } - BinaryData content = BinaryData.FromStream(bufferStream); bufferStream.Position = 0; - - return content; + ContentStream = bufferStream; + return bufferStream.Content; } /// - /// TBD. + /// Private Stream type to facilitate detecting whether abstract + /// ContentStream setter was called in order to invalidate cached + /// content returned from Content property. /// - /// - /// - /// - public override async ValueTask BufferContentAsync(CancellationToken cancellationToken = default) + private class BufferedContentStream : MemoryStream { - // Derived types should provide an implementation that allows caching - // to improve performance. - if (ContentStream is null) - { - return s_EmptyBinaryData; - } - - if (ContentStream is MemoryStream memoryStream) - { - return memoryStream.TryGetBuffer(out ArraySegment segment) ? + public static BinaryData FromBuffer(MemoryStream stream) + => stream.TryGetBuffer(out ArraySegment segment) ? new BinaryData(segment.AsMemory()) : - new BinaryData(memoryStream.ToArray()); - } + new BinaryData(stream.ToArray()); - BufferedContentStream bufferStream = new(); - - Stream? contentStream = ContentStream; - await contentStream.CopyToAsync(bufferStream, cancellationToken).ConfigureAwait(false); - contentStream.Dispose(); + public BinaryData Content => FromBuffer(this); + } - bufferStream.Position = 0; - ContentStream = bufferStream; + #endregion - BinaryData content = BinaryData.FromStream(bufferStream); - bufferStream.Position = 0; + /// + /// Creates a new instance of with the provided value and HTTP response. + /// + /// The type of the value. + /// The value. + /// The HTTP response. + /// A new instance of with the provided value and HTTP response. + public static Response FromValue(T value, Response response) + => new AzureCoreResponse(value, response); - return content; + /// + /// Returns the string representation of this . + /// + /// The string representation of this + public override string ToString() + { + return $"Status: {Status}, ReasonPhrase: {ReasonPhrase}"; } - private class BufferedContentStream : MemoryStream { } + internal static void DisposeStreamIfNotBuffered(ref Stream? stream) + { + // We want to keep the ContentStream readable + // even after the response is disposed but only if it's a + // buffered memory stream otherwise we can leave a network + // connection hanging open + if (stream is not MemoryStream) + { + stream?.Dispose(); + stream = null; + } + } - #region Private implementation subtypes of abstract Response types + /// + /// Internal implementation of abstract . + /// private class AzureCoreResponse : Response { public AzureCoreResponse(T value, Response response) : base(value, response) { } } - internal class AzureCoreDefaultResponse : Response + /// + /// This adapter adapts the Azure.Core + /// type to the System.ClientModel + /// interface, so that can implement the + /// property inherited from + /// . + /// + private class ResponseHeadersAdapter : PipelineResponseHeaders { - private readonly string DefaultMessage = "Types derived from abstract Response must provide an implementation of the virtual GetRawResponse method that returns a non-null Response value."; + /// + /// Headers on the Azure.Core Response type to adapt to. + /// + private readonly ResponseHeaders _headers; - public override string ClientRequestId + public ResponseHeadersAdapter(ResponseHeaders headers) { - get => throw new NotSupportedException(DefaultMessage); - set => throw new NotSupportedException(DefaultMessage); + _headers = headers; } - public override int Status => throw new NotSupportedException(DefaultMessage); + public override bool TryGetValue(string name, out string? value) + => _headers.TryGetValue(name, out value); - public override string ReasonPhrase => throw new NotSupportedException(DefaultMessage); + public override bool TryGetValues(string name, out IEnumerable? values) + => _headers.TryGetValues(name, out values); - public override Stream? ContentStream - { - get => throw new NotSupportedException(DefaultMessage); - set => throw new NotSupportedException(DefaultMessage); - } - - protected override PipelineResponseHeaders HeadersCore - => throw new NotSupportedException(DefaultMessage); - - public override void Dispose() - { - throw new NotSupportedException(DefaultMessage); - } + public override IEnumerator> GetEnumerator() + => GetHeaderValues().GetEnumerator(); - protected internal override bool ContainsHeader(string name) + private IEnumerable> GetHeaderValues() { - throw new NotSupportedException(DefaultMessage); - } - - protected internal override IEnumerable EnumerateHeaders() - { - throw new NotSupportedException(DefaultMessage); - } - - protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) - { - throw new NotSupportedException(DefaultMessage); - } - - protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) - { - throw new NotSupportedException(DefaultMessage); - } - - public override BinaryData BufferContent(CancellationToken cancellationToken = default) - { - throw new NotSupportedException(DefaultMessage); - } - - public override ValueTask BufferContentAsync(CancellationToken cancellationToken = default) - { - throw new NotSupportedException(DefaultMessage); + foreach (HttpHeader header in _headers) + { + yield return new KeyValuePair(header.Name, header.Value); + } } } - #endregion } } diff --git a/sdk/core/Azure.Core/src/ResponseOfT.cs b/sdk/core/Azure.Core/src/ResponseOfT.cs index 1b56dbd76bb3..2772247b9088 100644 --- a/sdk/core/Azure.Core/src/ResponseOfT.cs +++ b/sdk/core/Azure.Core/src/ResponseOfT.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel; using System.ComponentModel; using System.Diagnostics; @@ -19,10 +20,15 @@ public abstract class Response : NullableResponse #pragma warning restore SA1649 // File name should match first type name { /// - /// TBD. + /// Creates an instance of with no value + /// or . It is not intended for this constructor + /// to be called, as it will create an instance of + /// with null and + /// , neither of which is intended usage of this + /// type. /// [EditorBrowsable(EditorBrowsableState.Never)] - protected Response() : base(default, DefaultResponse) + protected Response() : base() { // Added for back-compat with GA APIs. Any type that derives from // Response must provide an implementation for GetRawResponse that @@ -31,10 +37,14 @@ protected Response() : base(default, DefaultResponse) } /// - /// TBD. + /// Creates an instance of from the provided + /// and . /// - /// - /// + /// The value to return from + /// on the created instance. + /// The to return from + /// on the created + /// instance. protected Response(T value, Response response) : base(value, response) { } /// diff --git a/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs b/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs index 3486de11775d..23a55986007b 100644 --- a/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs +++ b/sdk/core/Azure.Core/tests/NullableResponseOfTTests.cs @@ -29,7 +29,7 @@ public void DoesNotThrowWhenValueIsAccessedWithValue() [Test] public void ThrowsWhenValueIsAccessedWithNoValue_2_0() { - var target = new TestValueResponse2_0(new MockResponse(200)); + var target = new TestClientResultNullableResponse(new MockResponse(200)); Assert.Throws(() => { var val = target.Value; }); Assert.That(target.ToString(), Does.Contain("")); } @@ -37,7 +37,7 @@ public void ThrowsWhenValueIsAccessedWithNoValue_2_0() [Test] public void DoesNotThrowWhenValueIsAccessedWithValue_2_0() { - var target = new TestValueResponse2_0(new MockResponse(200), "test"); + var target = new TestClientResultNullableResponse(new MockResponse(200), "test"); Assert.AreEqual("test", target.Value); Assert.That(target.ToString(), Does.Not.Contain("")); Assert.That(target.ToString(), Does.Contain("test")); @@ -62,6 +62,7 @@ public TestValueResponse(Response response) _value = default; _hasValue = false; } + public override bool HasValue => _hasValue; public override T Value => _hasValue ? _value : throw new Exception("has no value"); @@ -69,19 +70,24 @@ public TestValueResponse(Response response) public override Response GetRawResponse() => _response; } - private class TestValueResponse2_0 : NullableResponse + // In contrast to TestValueResponse above, this derived type calls + // through to the protected constructors that take value and response. + private class TestClientResultNullableResponse : NullableResponse { private readonly bool _hasValue; - public TestValueResponse2_0(Response response, T value) : base(value, response) + public TestClientResultNullableResponse(Response response, T value) + : base(value, response) { _hasValue = true; } - public TestValueResponse2_0(Response response) : base(default, response) + public TestClientResultNullableResponse(Response response) + : base(default, response) { _hasValue = false; } + public override bool HasValue => _hasValue; public override T Value => _hasValue ? base.Value : throw new Exception("has no value"); From a3548d38ce2a126f265af6cb66ff577595670962 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 28 Feb 2024 10:12:51 -0800 Subject: [PATCH 39/47] Updates from #42255 --- sdk/core/Azure.Core/src/Response.cs | 10 +- sdk/core/Azure.Core/tests/ResponseTests.cs | 149 ++++++++++++++++++++- 2 files changed, 151 insertions(+), 8 deletions(-) diff --git a/sdk/core/Azure.Core/src/Response.cs b/sdk/core/Azure.Core/src/Response.cs index fb0e08b22c0e..9e4e405768a2 100644 --- a/sdk/core/Azure.Core/src/Response.cs +++ b/sdk/core/Azure.Core/src/Response.cs @@ -38,7 +38,8 @@ public abstract class Response : PipelineResponse /// Gets the contents of HTTP response, if it is available. /// /// - /// Throws when content is not buffered. + /// Throws when response content + /// has not been buffered by the pipeline. /// public override BinaryData Content { @@ -53,10 +54,7 @@ public override BinaryData Content } } - /// - /// Gets the value of on - /// the base type. - /// + /// protected override PipelineResponseHeaders HeadersCore => new ResponseHeadersAdapter(Headers); @@ -110,7 +108,7 @@ public override async ValueTask BufferContentAsync(CancellationToken => await BufferContentSyncOrAsync(cancellationToken, async: true).ConfigureAwait(false); /// - /// Provide a default implementation of the + /// Provide a default implementation of the abstract /// method inherited from /// . This is used by any types derived /// from that don't override the BufferContent diff --git a/sdk/core/Azure.Core/tests/ResponseTests.cs b/sdk/core/Azure.Core/tests/ResponseTests.cs index 32d5bbd3c43f..30a9dc8ed442 100644 --- a/sdk/core/Azure.Core/tests/ResponseTests.cs +++ b/sdk/core/Azure.Core/tests/ResponseTests.cs @@ -3,15 +3,26 @@ using System; using System.IO; -using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Azure.Core.Pipeline; using Azure.Core.TestFramework; -using NUnit.Framework; using Moq; +using NUnit.Framework; namespace Azure.Core.Tests { + [TestFixture(true)] + [TestFixture(false)] public class ResponseTests { + private readonly bool _isAsync; + + public ResponseTests(bool isAsync) + { + _isAsync = isAsync; + } + [Test] public void ValueIsAccessible() { @@ -170,6 +181,108 @@ public void CanMoqIsError() Assert.IsTrue(response.Object.IsError); } + [Test] + public void ResponseBuffersContentFromContentStream() + { + BinaryData mockContent = BinaryData.FromString("Mock content"); + MemoryStream mockContentStream = new(mockContent.ToArray()); + + MockResponse response = new(200); + response.ContentStream = mockContentStream; + + Assert.AreEqual(mockContent.ToString(), response.Content.ToString()); + } + + [Test] + public void BufferedResponseContentEmptyWhenNoResponseContent() + { + MockResponse response = new(200); + + Assert.AreEqual(0, response.Content.ToMemory().Length); + } + + [Test] + public void BufferedResponseContentAvailableAfterResponseDisposed() + { + BinaryData mockContent = BinaryData.FromString("Mock content"); + MemoryStream mockContentStream = new(mockContent.ToArray()); + + MockResponse response = new(200); + response.ContentStream = mockContentStream; + + Assert.AreEqual(mockContent.ToString(), response.Content.ToString()); + + response.Dispose(); + + Assert.AreEqual(mockContent.ToString(), response.Content.ToString()); + Assert.AreEqual(mockContent.ToString(), BinaryData.FromStream(response.ContentStream).ToString()); + } + + [Test] + public void UnbufferedResponseContentThrows() + { + BinaryData mockContent = BinaryData.FromString("Mock content"); + MockNetworkStream mockContentStream = new(mockContent.ToArray()); + + MockResponse response = new(200); + response.ContentStream = mockContentStream; + + Assert.Throws(() => { var content = response.Content; }); + } + + [Test] + public async Task BufferContentReturnsContentIfBuffered() + { + BinaryData mockContent = BinaryData.FromString("Mock content"); + MemoryStream mockContentStream = new(mockContent.ToArray()); + + MockResponse response = new(200); + response.ContentStream = mockContentStream; + + BinaryData content = await BufferContentAsync(response); + + Assert.AreEqual(response.Content.ToArray(), content.ToArray()); + } + + [Test] + public async Task BufferContentReturnsEmptyWhenNoResponseContent() + { + MockResponse response = new(200); + + BinaryData content = await BufferContentAsync(response); + + Assert.AreEqual(response.Content.ToArray(), content.ToArray()); + } + + [Test] + public async Task CachedResponseContentReplacedWhenContentStreamReplaced() + { + BinaryData mockContent = BinaryData.FromString("Mock content"); + MemoryStream mockContentStream = new(mockContent.ToArray()); + + MockResponse response = new(200); + response.ContentStream = mockContentStream; + + BinaryData content = await BufferContentAsync(response); + + Assert.AreEqual(response.Content.ToArray(), content.ToArray()); + + // Replace content stream + response.ContentStream = new MemoryStream(Encoding.UTF8.GetBytes("Mock content - 2")); + + Assert.AreEqual("Mock content - 2", response.Content.ToString()); + Assert.AreEqual("Mock content - 2", BinaryData.FromStream(response.ContentStream!).ToString()); + } + + #region Helpers + + private async Task BufferContentAsync(Response response) + { + return _isAsync ? + await response.BufferContentAsync() : + response.BufferContent(); + } + internal class TestPayload { public string Name { get; } @@ -222,5 +335,37 @@ public override void Write(byte[] buffer, int offset, int count) throw new System.NotImplementedException(); } } + + private class MockNetworkStream : ReadOnlyStream + { + private readonly MemoryStream _stream; + + public MockNetworkStream(byte[] content) + { + _stream = new MemoryStream(content); + } + + public override bool CanRead => true; + + public override bool CanSeek => false; + + public override long Length => _stream.Length; + + public override long Position + { + get => _stream.Position; + set => throw new NotSupportedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + => _stream.Read(buffer, offset, count); + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + } + + #endregion } } From b24647de03745578ccfc24fc138fdd10a44c10c6 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Wed, 28 Feb 2024 18:20:16 -0800 Subject: [PATCH 40/47] Updates from #42262 --- sdk/core/Azure.Core/src/HttpMessage.cs | 24 +++--- .../Pipeline/HttpClientTransport.Adapter.cs | 4 +- .../Azure.Core/src/Pipeline/HttpPipeline.cs | 28 +++---- .../Pipeline/HttpPipelineTransport.Adapter.cs | 4 +- .../src/Pipeline/RetryPolicy.Adapter.cs | 16 ++-- sdk/core/Azure.Core/src/ResponseClassifier.cs | 81 +++++++++++++------ sdk/core/Azure.Core/tests/HttpMessageTests.cs | 14 ++++ .../tests/ResponseClassifierTests.cs | 17 ++++ 8 files changed, 125 insertions(+), 63 deletions(-) diff --git a/sdk/core/Azure.Core/src/HttpMessage.cs b/sdk/core/Azure.Core/src/HttpMessage.cs index 803fdc977e12..3e44ef144908 100644 --- a/sdk/core/Azure.Core/src/HttpMessage.cs +++ b/sdk/core/Azure.Core/src/HttpMessage.cs @@ -48,7 +48,9 @@ public HttpMessage(Request request, ResponseClassifier responseClassifier) throw new InvalidOperationException($"{nameof(Response)} is not set on this message. " + "This is may be because the message was not sent via pipeline.Send, " + "the pipeline transport did not populate the response, or because " - + $"{nameof(ExtractResponse)} was called."); + + $"{nameof(ExtractResponse)} was called. You can check the {nameof(HasResponse)} " + + "property to test whether the message has a response value before " + + $"accessing the {nameof(Response)} property."); #pragma warning restore CA1065 // Do not raise exceptions in unexpected locations } return (Response)base.Response; @@ -69,7 +71,12 @@ public HttpMessage(Request request, ResponseClassifier responseClassifier) /// public new ResponseClassifier ResponseClassifier { - get => (ResponseClassifier)base.ResponseClassifier; + get => base.ResponseClassifier switch + { + ResponseClassifier responseClassifier => responseClassifier, + PipelineMessageClassifier messageClassifier => new ResponseClassifier.PipelineMessageClassifierAdapter(messageClassifier) + }; + set => base.ResponseClassifier = value; } @@ -89,7 +96,6 @@ internal void ApplyRequestContext(RequestContext context, ResponseClassifier? cl { context.Freeze(); - // Azure-specific extensibility piece if (context.Policies?.Count > 0) { Policies ??= new(context.Policies.Count); @@ -106,7 +112,7 @@ internal void ApplyRequestContext(RequestContext context, ResponseClassifier? cl internal List<(HttpPipelinePosition Position, HttpPipelinePolicy Policy)>? Policies { get; set; } - internal static HttpMessage AssertHttpMessage(PipelineMessage message) + internal static HttpMessage GetHttpMessage(PipelineMessage message) { if (message is not HttpMessage httpMessage) { @@ -172,12 +178,7 @@ private class MessagePropertyKey { } /// did not have content set. public Stream? ExtractResponseContent() { - if (!HasResponse) - { - return null; - } - - switch (Response.ContentStream) + switch (Response?.ContentStream) { case ResponseShouldNotBeUsedStream responseContent: return responseContent.Original; @@ -196,7 +197,8 @@ private class MessagePropertyKey { } /// null and the caller will be responsible for disposing the returned /// value, which may hold a live network stream. /// - public new Response? ExtractResponse() => (Response?)base.ExtractResponse(); + public new Response? ExtractResponse() + => (Response?)base.ExtractResponse(); private class ResponseShouldNotBeUsedStream : Stream { diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs index 7742ce76d86a..6e5e8867a9c0 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs @@ -32,7 +32,7 @@ protected override PipelineMessage CreateMessageCore() /// protected override void OnSendingRequest(PipelineMessage message, HttpRequestMessage httpRequest) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); HttpClientTransportRequest.AddAzureProperties(httpMessage, httpRequest); httpMessage.ClearResponse(); } @@ -40,7 +40,7 @@ protected override void OnSendingRequest(PipelineMessage message, HttpRequestMes /// protected override void OnReceivedResponse(PipelineMessage message, HttpResponseMessage httpResponse) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); string clientRequestId = httpMessage.Request.ClientRequestId; PipelineResponse pipelineResponse = message.Response!; httpMessage.Response = new HttpClientTransportResponse(clientRequestId, pipelineResponse); diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs index 1df9052396e0..bb0a27eaeff0 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs @@ -195,23 +195,17 @@ public void Send(HttpMessage message, CancellationToken cancellationToken) } else { - Send(message); - } - } - - private void Send(HttpMessage message) - { - int length = _pipeline.Length + message.Policies!.Count; - HttpPipelinePolicy[] policies = ArrayPool.Shared.Rent(length); - - try - { - ReadOnlyMemory pipeline = CreateRequestPipeline(policies, message.Policies); - pipeline.Span[0].Process(message, pipeline.Slice(1)); - } - finally - { - ArrayPool.Shared.Return(policies); + int length = _pipeline.Length + message.Policies.Count; + HttpPipelinePolicy[] policies = ArrayPool.Shared.Rent(length); + try + { + ReadOnlyMemory pipeline = CreateRequestPipeline(policies, message.Policies); + pipeline.Span[0].Process(message, pipeline.Slice(1)); + } + finally + { + ArrayPool.Shared.Return(policies); + } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs index 3098603c1eea..814ffc00431a 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs @@ -26,13 +26,13 @@ protected override PipelineMessage CreateMessageCore() protected override void ProcessCore(PipelineMessage message) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); _transport.Process(httpMessage); } protected override async ValueTask ProcessCoreAsync(PipelineMessage message) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); await _transport.ProcessAsync(httpMessage).ConfigureAwait(false); } } diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs index 09230a634cdb..92c9a1a2722a 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs @@ -35,19 +35,19 @@ protected override void OnSendingRequest(PipelineMessage message) { _beforeProcess = Stopwatch.GetTimestamp(); - _pipelinePolicy.OnSendingRequest(HttpMessage.AssertHttpMessage(message)); + _pipelinePolicy.OnSendingRequest(HttpMessage.GetHttpMessage(message)); } protected override async ValueTask OnSendingRequestAsync(PipelineMessage message) { _beforeProcess = Stopwatch.GetTimestamp(); - await _pipelinePolicy.OnSendingRequestAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); + await _pipelinePolicy.OnSendingRequestAsync(HttpMessage.GetHttpMessage(message)).ConfigureAwait(false); } protected override void OnRequestSent(PipelineMessage message) { - _pipelinePolicy.OnRequestSent(HttpMessage.AssertHttpMessage(message)); + _pipelinePolicy.OnRequestSent(HttpMessage.GetHttpMessage(message)); _afterProcess = Stopwatch.GetTimestamp(); _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; @@ -55,21 +55,21 @@ protected override void OnRequestSent(PipelineMessage message) protected override async ValueTask OnRequestSentAsync(PipelineMessage message) { - await _pipelinePolicy.OnRequestSentAsync(HttpMessage.AssertHttpMessage(message)).ConfigureAwait(false); + await _pipelinePolicy.OnRequestSentAsync(HttpMessage.GetHttpMessage(message)).ConfigureAwait(false); _afterProcess = Stopwatch.GetTimestamp(); _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; } protected override bool ShouldRetry(PipelineMessage message, Exception? exception) - => _pipelinePolicy.ShouldRetry(HttpMessage.AssertHttpMessage(message), exception); + => _pipelinePolicy.ShouldRetry(HttpMessage.GetHttpMessage(message), exception); protected override async ValueTask ShouldRetryAsync(PipelineMessage message, Exception? exception) - => await _pipelinePolicy.ShouldRetryAsync(HttpMessage.AssertHttpMessage(message), exception).ConfigureAwait(false); + => await _pipelinePolicy.ShouldRetryAsync(HttpMessage.GetHttpMessage(message), exception).ConfigureAwait(false); protected override void OnTryComplete(PipelineMessage message) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); httpMessage.RetryNumber++; AzureCoreEventSource.Singleton.RequestRetrying(httpMessage.Request.ClientRequestId, httpMessage.RetryNumber, _elapsedTime); @@ -82,7 +82,7 @@ protected override void OnTryComplete(PipelineMessage message) protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); Debug.Assert(tryCount == httpMessage.RetryNumber); diff --git a/sdk/core/Azure.Core/src/ResponseClassifier.cs b/sdk/core/Azure.Core/src/ResponseClassifier.cs index a9ee3cb1358f..5dbb3488b54a 100644 --- a/sdk/core/Azure.Core/src/ResponseClassifier.cs +++ b/sdk/core/Azure.Core/src/ResponseClassifier.cs @@ -43,8 +43,14 @@ public virtual bool IsRetriableException(Exception exception) /// public virtual bool IsRetriable(HttpMessage message, Exception exception) { - // Azure.Core cannot use default logic in this case to support end-user overrides - // of virtual IsRetriableException method. + if (exception is null) + { + return IsErrorResponse(message); + } + + // In order to allow users to override IsRetriableException logic, + // we must call through to that rather than using the base type + // default implementation. return IsRetriableException(exception) || // Retry non-user initiated cancellations @@ -64,39 +70,22 @@ public virtual bool IsErrorResponse(HttpMessage message) return isError; } - /// - /// TBD. - /// - /// - /// - /// + /// [EditorBrowsable(EditorBrowsableState.Never)] - // TODO: Add a test that breaks if we unseal this to prevent that from happening - // Note: this is sealed to force the base type to call through to any overridden virtual methods - // on a subtype of ResponseClassifier. public sealed override bool TryClassify(PipelineMessage message, out bool isError) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); isError = IsErrorResponse(httpMessage); return true; } - /// - /// TBD. - /// - /// - /// - /// - /// + /// [EditorBrowsable(EditorBrowsableState.Never)] - // TODO: Add a test that breaks if we unseal this to prevent that from happening - // Note: this is sealed to force the base type to call through to any overridden virtual methods - // on a subtype of ResponseClassifier. public sealed override bool TryClassify(PipelineMessage message, Exception? exception, out bool isRetriable) { - HttpMessage httpMessage = HttpMessage.AssertHttpMessage(message); + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); isRetriable = exception is null ? IsRetriableResponse(httpMessage) : @@ -104,5 +93,51 @@ public sealed override bool TryClassify(PipelineMessage message, Exception? exce return true; } + + /// + /// This adapter adapts the System.ClientModel + /// type to the Azure.Core + /// interface, so that it can be used + /// as though it were a ResponseClassifier in Azure.Core. + /// + internal sealed class PipelineMessageClassifierAdapter : ResponseClassifier + { + private readonly PipelineMessageClassifier _classifier; + + public PipelineMessageClassifierAdapter(PipelineMessageClassifier classifier) + { + _classifier = classifier; + } + + public override bool IsErrorResponse(HttpMessage message) + { + bool classified = _classifier.TryClassify(message, out bool isError); + + Debug.Assert(classified); + + return isError; + } + + public override bool IsRetriable(HttpMessage message, Exception exception) + { + bool classified = _classifier.TryClassify(message, exception, out bool isRetriable); + + Debug.Assert(classified); + + return isRetriable; + } + + public override bool IsRetriableException(Exception exception) + => base.IsRetriableException(exception); + + public override bool IsRetriableResponse(HttpMessage message) + { + bool classified = _classifier.TryClassify(message, exception: default, out bool isRetriable); + + Debug.Assert(classified); + + return isRetriable; + } + } } } diff --git a/sdk/core/Azure.Core/tests/HttpMessageTests.cs b/sdk/core/Azure.Core/tests/HttpMessageTests.cs index 030b176bac56..a294c4d3a806 100644 --- a/sdk/core/Azure.Core/tests/HttpMessageTests.cs +++ b/sdk/core/Azure.Core/tests/HttpMessageTests.cs @@ -7,6 +7,7 @@ using Azure.Core.Pipeline; using Azure.Core.TestFramework; using NUnit.Framework; +using System.ClientModel.Primitives; namespace Azure.Core.Tests { @@ -383,6 +384,19 @@ public void AppliesHandlerWithLastSetWinsSemantics() Assert.IsTrue(message.ResponseClassifier.IsErrorResponse(message)); } + [Test] + public void SettingBaseClassifierSetsHttpMessageClassifier() + { + MockRequest request = new(); + HttpMessage message = new(request, ResponseClassifier.Shared); + message.Response = new MockResponse(400); + + PipelineMessage pipelineMessage = message; + pipelineMessage.ResponseClassifier = PipelineMessageClassifier.Default; + + Assert.IsTrue(message.ResponseClassifier.IsErrorResponse(message)); + } + [Test] [TestCase(true)] [TestCase(false)] diff --git a/sdk/core/Azure.Core/tests/ResponseClassifierTests.cs b/sdk/core/Azure.Core/tests/ResponseClassifierTests.cs index 966aad41185c..73a09cc3d907 100644 --- a/sdk/core/Azure.Core/tests/ResponseClassifierTests.cs +++ b/sdk/core/Azure.Core/tests/ResponseClassifierTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.Reflection; using Azure.Core.TestFramework; using NUnit.Framework; @@ -97,5 +98,21 @@ public void SharedClassifierClassifiesErrorResponse(int code, bool isError) Assert.AreEqual(isError, classifier.IsErrorResponse(message)); } + + [Test] + public void TryClassifyIsSealed() + { + // It is important that ResponseClassifier.TryClassify methods are sealed + // so that when TryClassify is called from the base PipelineMessageClassifier + // it calls through to the ResponseClassifier implementation of IsError + // and IsRetriable methods. + + Type type = typeof(ResponseClassifier); + MethodInfo tryClassifyError = type.GetMethod("TryClassify", new Type[] { typeof(HttpMessage), typeof(bool).MakeByRefType() }); + MethodInfo tryClassifyRetriable = type.GetMethod("TryClassify", new Type[] { typeof(HttpMessage), typeof(Exception), typeof(bool).MakeByRefType() }); + + Assert.True(tryClassifyError.IsFinal); + Assert.True(tryClassifyRetriable.IsFinal); + } } } From 23fce2f96020d66e3c35fc82aff0455871a4dc60 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Thu, 29 Feb 2024 14:16:33 -0800 Subject: [PATCH 41/47] updates from #42262 --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 1 + sdk/core/Azure.Core/api/Azure.Core.net472.cs | 1 + sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 1 + .../api/Azure.Core.netstandard2.0.cs | 1 + sdk/core/Azure.Core/src/HttpMessage.cs | 33 ++++---------- .../Azure.Core/src/NullableResponseOfT.cs | 24 ++++++---- .../Azure.Core/src/Pipeline/HttpPipeline.cs | 4 +- sdk/core/Azure.Core/src/RequestContext.cs | 29 +++++++++--- sdk/core/Azure.Core/tests/HttpMessageTests.cs | 44 +++++++++---------- .../api/System.ClientModel.net6.0.cs | 1 + .../api/System.ClientModel.netstandard2.0.cs | 1 + .../src/Message/PipelineMessage.cs | 12 ++--- .../src/Options/RequestOptions.cs | 9 +++- 13 files changed, 91 insertions(+), 70 deletions(-) diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index cf12221fe86e..7441102480a5 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -216,6 +216,7 @@ public RequestContext() { } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } + protected override void Apply(System.ClientModel.Primitives.PipelineMessage message) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index cf12221fe86e..7441102480a5 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -216,6 +216,7 @@ public RequestContext() { } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } + protected override void Apply(System.ClientModel.Primitives.PipelineMessage message) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index e4daa01280ac..6a406d4246c8 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -216,6 +216,7 @@ public RequestContext() { } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } + protected override void Apply(System.ClientModel.Primitives.PipelineMessage message) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index cf12221fe86e..7441102480a5 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -216,6 +216,7 @@ public RequestContext() { } public void AddClassifier(Azure.Core.ResponseClassificationHandler classifier) { } public void AddClassifier(int statusCode, bool isError) { } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } + protected override void Apply(System.ClientModel.Primitives.PipelineMessage message) { } public static implicit operator Azure.RequestContext (Azure.ErrorOptions options) { throw null; } } public partial class RequestFailedException : System.ClientModel.ClientResultException, System.Runtime.Serialization.ISerializable diff --git a/sdk/core/Azure.Core/src/HttpMessage.cs b/sdk/core/Azure.Core/src/HttpMessage.cs index 3e44ef144908..4bf47b1ab063 100644 --- a/sdk/core/Azure.Core/src/HttpMessage.cs +++ b/sdk/core/Azure.Core/src/HttpMessage.cs @@ -45,12 +45,15 @@ public HttpMessage(Request request, ResponseClassifier responseClassifier) if (base.Response is null) { #pragma warning disable CA1065 // Do not raise exceptions in unexpected locations - throw new InvalidOperationException($"{nameof(Response)} is not set on this message. " - + "This is may be because the message was not sent via pipeline.Send, " - + "the pipeline transport did not populate the response, or because " - + $"{nameof(ExtractResponse)} was called. You can check the {nameof(HasResponse)} " - + "property to test whether the message has a response value before " - + $"accessing the {nameof(Response)} property."); + throw new InvalidOperationException($""" + {nameof(Response)} is not set on this message. This + may be because the message was not sent via + pipeline.Send, the pipeline transport did not populate + the response, or because {nameof(ExtractResponse)} was + called. You can check the {nameof(HasResponse)} + property to test whether the message has a response + value before accessing the {nameof(Response)} property. + """); #pragma warning restore CA1065 // Do not raise exceptions in unexpected locations } return (Response)base.Response; @@ -92,24 +95,6 @@ internal void SetCancellationToken(CancellationToken cancellationToken) /// public MessageProcessingContext ProcessingContext => new(this); - internal void ApplyRequestContext(RequestContext context, ResponseClassifier? classifier) - { - context.Freeze(); - - if (context.Policies?.Count > 0) - { - Policies ??= new(context.Policies.Count); - Policies.AddRange(context.Policies); - } - - if (classifier != null) - { - ResponseClassifier = context.Apply(classifier); - } - - Apply(context); - } - internal List<(HttpPipelinePosition Position, HttpPipelinePolicy Policy)>? Policies { get; set; } internal static HttpMessage GetHttpMessage(PipelineMessage message) diff --git a/sdk/core/Azure.Core/src/NullableResponseOfT.cs b/sdk/core/Azure.Core/src/NullableResponseOfT.cs index dca69945143a..53871e8e4bed 100644 --- a/sdk/core/Azure.Core/src/NullableResponseOfT.cs +++ b/sdk/core/Azure.Core/src/NullableResponseOfT.cs @@ -87,14 +87,22 @@ public override string ToString() private static Response ReplaceWithDefaultIfNull(Response? response) => response ?? DefaultRawResponse; - // This nested type enables back-compatibility with the protected - // parameterless contructor on NullableResponse. It implements - // Response so that a non-null PipelineResponse can be passed to the - // base ClientResult constructor to prevent an ArgumentNullException - // from being thrown. Any caller that accesses this Response via - // GetRawResponse on the NullableResponse instance will get an - // exception saying that the derived type has been implemented - // incorrectly. + // This type exists because of the following reasons: + // 1. The base ClientResult constructor requires a non-null instance + // of PipelineResponse. + // 2. NullableResponse was GA'ed with a protected parameterless + // default constructor before inheriting from the base + // ClientResult class. + // 3. The new implementation of the default constructor must pass an + // instance of this dummy type to the base constructor. + // + // Because the intent of NullableResponse and Response is to + // always return a Response value from GetRawResponse, it is incorrect + // for types derived from them to return null from GetRawResponse, and + // instances of this type should only be created when the derived type + // has been implemented incorrectly. If an instance of this type is + // returned from GetRawResponse, callers who access its properties will + // get a NotSupportedException. private class DefaultResponse : Response { private readonly string ExceptionMessage = "Types derived from abstract NullableResponse or Response must provide an implementation of the virtual GetRawResponse method that returns a non-null Response value."; diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs index bb0a27eaeff0..2d2890f9a935 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipeline.cs @@ -123,9 +123,9 @@ public HttpMessage CreateMessage(RequestContext? context, ResponseClassifier? cl Request request = CreateRequest(); HttpMessage message = new(request, classifier ?? ResponseClassifier); - if (context != null) + if (context is not null) { - message.ApplyRequestContext(context, classifier); + message.Apply(context); } return message; diff --git a/sdk/core/Azure.Core/src/RequestContext.cs b/sdk/core/Azure.Core/src/RequestContext.cs index de5e5cbaf1e2..38abbdb6629c 100644 --- a/sdk/core/Azure.Core/src/RequestContext.cs +++ b/sdk/core/Azure.Core/src/RequestContext.cs @@ -4,6 +4,7 @@ using System; using System.ClientModel.Primitives; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Azure.Core; using Azure.Core.Pipeline; @@ -31,25 +32,23 @@ public class RequestContext : RequestOptions set => base.ErrorOptions = ToResponseErrorOptions(value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ErrorOptions FromResponseErrorOptions(ClientErrorBehaviors options) - { - return options switch + => options switch { ClientErrorBehaviors.Default => ErrorOptions.Default, ClientErrorBehaviors.NoThrow => ErrorOptions.NoThrow, _ => throw new NotSupportedException(), }; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ClientErrorBehaviors ToResponseErrorOptions(ErrorOptions options) - { - return options switch + => options switch { ErrorOptions.Default => ClientErrorBehaviors.Default, ErrorOptions.NoThrow => ClientErrorBehaviors.NoThrow, _ => throw new NotSupportedException(), }; - } /// /// Initializes a new instance of the class. @@ -127,7 +126,23 @@ public void AddClassifier(ResponseClassificationHandler classifier) _handlers[0] = classifier; } - internal ResponseClassifier Apply(ResponseClassifier classifier) + /// + protected override void Apply(PipelineMessage message) + { + base.Apply(message); + + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); + + if (Policies?.Count > 0) + { + httpMessage.Policies ??= new(Policies.Count); + httpMessage.Policies.AddRange(Policies); + } + + httpMessage.ResponseClassifier = ApplyClassifier(httpMessage.ResponseClassifier); + } + + private ResponseClassifier ApplyClassifier(ResponseClassifier classifier) { if (_statusCodes == null && _handlers == null) { diff --git a/sdk/core/Azure.Core/tests/HttpMessageTests.cs b/sdk/core/Azure.Core/tests/HttpMessageTests.cs index a294c4d3a806..55873d1d60a6 100644 --- a/sdk/core/Azure.Core/tests/HttpMessageTests.cs +++ b/sdk/core/Azure.Core/tests/HttpMessageTests.cs @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Threading.Tasks; -using System.Threading; using System; +using System.ClientModel.Primitives; +using System.Threading; +using System.Threading.Tasks; using Azure.Core.Pipeline; using Azure.Core.TestFramework; using NUnit.Framework; -using System.ClientModel.Primitives; namespace Azure.Core.Tests { @@ -96,8 +96,8 @@ public void AppliesResponseClassifierErrors() RequestContext context = new RequestContext(); context.AddClassifier(204, isError: true); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, ResponseClassifier200204304); + HttpMessage message = new HttpMessage(new MockRequest(), ResponseClassifier200204304); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsTrue(message.ResponseClassifier.IsErrorResponse(message)); @@ -118,8 +118,8 @@ public void AppliesResponseClassifierNonErrors() RequestContext context = new RequestContext(); context.AddClassifier(404, isError: false); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, ResponseClassifier200204304); + HttpMessage message = new HttpMessage(new MockRequest(), ResponseClassifier200204304); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsFalse(message.ResponseClassifier.IsErrorResponse(message)); @@ -142,8 +142,8 @@ public void AppliesResponseClassifierBothErrorsAndNonErrors() context.AddClassifier(304, isError: true); context.AddClassifier(404, isError: false); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, ResponseClassifier200204304); + HttpMessage message = new HttpMessage(new MockRequest(), ResponseClassifier200204304); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsFalse(message.ResponseClassifier.IsErrorResponse(message)); @@ -197,7 +197,7 @@ public void SettingResponseClassifierReplacesBaseClassifier_PerCallCustomization RequestContext context = new RequestContext(); context.AddClassifier(new StatusCodeHandler(304, true)); - message.ResponseClassifier = context.Apply(ResponseClassifier200204304); + message.Apply(context); // This replaces the base classifier with one that only thinks 404 is a non-error // and doesn't have opinions on anything else. @@ -256,8 +256,8 @@ public void AppliesHandler() RequestContext context = new RequestContext(); context.AddClassifier(new StatusCodeHandler(204, isError: true)); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, ResponseClassifier200204304); + HttpMessage message = new HttpMessage(new MockRequest(), ResponseClassifier200204304); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsTrue(message.ResponseClassifier.IsErrorResponse(message)); @@ -279,8 +279,8 @@ public void AppliesHandlerBeforeResponseClassifier() context.AddClassifier(new StatusCodeHandler(204, true)); context.AddClassifier(204, isError: false); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, ResponseClassifier200204304); + HttpMessage message = new HttpMessage(new MockRequest(), ResponseClassifier200204304); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsTrue(message.ResponseClassifier.IsErrorResponse(message)); @@ -298,8 +298,8 @@ public void AppliesHandlerBeforeResponseClassifier() [Test] public void AppliesNonStatusCodeClassifier_HeadResponseClassifier() { - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(new RequestContext(), HeadResponseClassifier.Instance); + HttpMessage message = new HttpMessage(new MockRequest(), HeadResponseClassifier.Instance); + message.Apply(new RequestContext()); message.Response = new MockResponse(204); Assert.IsFalse(message.ResponseClassifier.IsErrorResponse(message)); @@ -321,8 +321,8 @@ public void ChainsClassifiers_StatusCodes() context.AddClassifier(404, true); context.AddClassifier(500, false); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, HeadResponseClassifier.Instance); + HttpMessage message = new HttpMessage(new MockRequest(), HeadResponseClassifier.Instance); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsFalse(message.ResponseClassifier.IsErrorResponse(message)); @@ -345,8 +345,8 @@ public void ChainsClassifiers_StatusCodesAndHandlers() context.AddClassifier(500, false); context.AddClassifier(new StatusCodeHandler(404, true)); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, HeadResponseClassifier.Instance); + HttpMessage message = new HttpMessage(new MockRequest(), HeadResponseClassifier.Instance); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsFalse(message.ResponseClassifier.IsErrorResponse(message)); @@ -368,8 +368,8 @@ public void AppliesHandlerWithLastSetWinsSemantics() context.AddClassifier(new StatusCodeHandler(204, true)); context.AddClassifier(new StatusCodeHandler(204, false)); - HttpMessage message = new HttpMessage(new MockRequest(), default); - message.ApplyRequestContext(context, ResponseClassifier200204304); + HttpMessage message = new HttpMessage(new MockRequest(), ResponseClassifier200204304); + message.Apply(context); message.Response = new MockResponse(204); Assert.IsFalse(message.ResponseClassifier.IsErrorResponse(message)); diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs index f37941fb2731..0756eb961907 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs @@ -244,6 +244,7 @@ public RequestOptions() { } public System.ClientModel.Primitives.ClientErrorBehaviors ErrorOptions { get { throw null; } set { } } public void AddHeader(string name, string value) { } public void AddPolicy(System.ClientModel.Primitives.PipelinePolicy policy, System.ClientModel.Primitives.PipelinePosition position) { } + protected internal virtual void Apply(System.ClientModel.Primitives.PipelineMessage message) { } protected void AssertNotFrozen() { } public virtual void Freeze() { } public void SetHeader(string name, string value) { } diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs index e23c8f4bfff7..d6220b4a1441 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs @@ -243,6 +243,7 @@ public RequestOptions() { } public System.ClientModel.Primitives.ClientErrorBehaviors ErrorOptions { get { throw null; } set { } } public void AddHeader(string name, string value) { } public void AddPolicy(System.ClientModel.Primitives.PipelinePolicy policy, System.ClientModel.Primitives.PipelinePosition position) { } + protected internal virtual void Apply(System.ClientModel.Primitives.PipelineMessage message) { } protected void AssertNotFrozen() { } public virtual void Freeze() { } public void SetHeader(string name, string value) { } diff --git a/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs b/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs index 1345c1ccc8b4..b418189f6efd 100644 --- a/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs +++ b/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs @@ -104,17 +104,19 @@ public CancellationToken CancellationToken /// /// Apply the options from the provided to - /// this instance. This method is intended to - /// be called after the creation of the and - /// its is complete, and prior to the call to - /// . + /// this instance. /// /// The to apply to this /// instance. + /// This method is intended to be called after the creation of + /// the and its is + /// complete, and prior to the call to + /// . + /// public void Apply(RequestOptions options) { // This design moves the client-author API (options.Apply) off the - // client-user type RequestOptions. Its only purpose is to call through to + // client-user type RequestOptions. Its only purpose is to call through to // the internal options.Apply method. options.Apply(this); } diff --git a/sdk/core/System.ClientModel/src/Options/RequestOptions.cs b/sdk/core/System.ClientModel/src/Options/RequestOptions.cs index 367f8d8baede..1d1665eba6e6 100644 --- a/sdk/core/System.ClientModel/src/Options/RequestOptions.cs +++ b/sdk/core/System.ClientModel/src/Options/RequestOptions.cs @@ -128,8 +128,13 @@ public void AddPolicy(PipelinePolicy policy, PipelinePosition position) } } - // Set options on the message before sending it through the pipeline. - internal void Apply(PipelineMessage message) + /// + /// Apply the options provided in this + /// instance to the . + /// + /// The to apply the + /// options to. + protected internal virtual void Apply(PipelineMessage message) { Freeze(); From 260ad2bfe83a4191ab86b7569d7332f10b18614b Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 1 Mar 2024 08:44:55 -0800 Subject: [PATCH 42/47] stay in sync with #42294 --- sdk/core/Azure.Core/src/HttpMessage.cs | 4 +- .../Internal/AzureCorePipelineProcessor.cs | 75 ----------- .../Pipeline/HttpClientTransport.Adapter.cs | 50 -------- .../Pipeline/HttpClientTransport.Request.cs | 88 +++++++------ .../Pipeline/HttpClientTransport.Response.cs | 52 ++++---- .../src/Pipeline/HttpClientTransport.cs | 47 ++++++- .../src/Pipeline/HttpPipelinePolicy.cs | 117 +++++++++++++++--- .../Pipeline/HttpPipelineTransport.Adapter.cs | 39 ------ .../src/Pipeline/HttpPipelineTransport.cs | 40 +++--- .../Internal/HttpPipelineTransportPolicy.cs | 7 +- .../Azure.Core/src/Pipeline/RetryPolicy.cs | 6 +- 11 files changed, 251 insertions(+), 274 deletions(-) delete mode 100644 sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs delete mode 100644 sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs delete mode 100644 sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs diff --git a/sdk/core/Azure.Core/src/HttpMessage.cs b/sdk/core/Azure.Core/src/HttpMessage.cs index 4bf47b1ab063..75f0b9ff76be 100644 --- a/sdk/core/Azure.Core/src/HttpMessage.cs +++ b/sdk/core/Azure.Core/src/HttpMessage.cs @@ -97,11 +97,11 @@ internal void SetCancellationToken(CancellationToken cancellationToken) internal List<(HttpPipelinePosition Position, HttpPipelinePolicy Policy)>? Policies { get; set; } - internal static HttpMessage GetHttpMessage(PipelineMessage message) + internal static HttpMessage GetHttpMessage(PipelineMessage message, string? errorMessage = default) { if (message is not HttpMessage httpMessage) { - throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'."); + throw new InvalidOperationException($"Invalid type for PipelineMessage: '{message?.GetType()}'. {errorMessage}"); } return httpMessage; diff --git a/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs b/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs deleted file mode 100644 index 28669ffd0e34..000000000000 --- a/sdk/core/Azure.Core/src/Internal/AzureCorePipelineProcessor.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.ClientModel.Primitives; -using System.Collections; -using System.Collections.Generic; - -namespace Azure.Core.Pipeline -{ - /// - /// Adapter from an Azure.Core pipeline to a System.ClientModel pipeline. - /// Azure.Core policies take - /// as the pipeline parameter of their - /// methods. System.ClientModel policies take . - /// - /// This type allows Azure.Core policies such as to - /// hold System.ClientModel policies internally and call their process methods - /// in a way that will continue passing control down the chain of policies. - /// - internal struct AzureCorePipelineProcessor : IReadOnlyList - { - private readonly ReadOnlyMemory _policies; - private PolicyEnumerator? _enumerator; - - public AzureCorePipelineProcessor(ReadOnlyMemory policies) - => _policies = policies; - - public ReadOnlyMemory Policies - => _policies; - - public PipelinePolicy this[int index] => _policies.Span[index]; - - public int Count => _policies.Length; - - public IEnumerator GetEnumerator() - => _enumerator ??= new(this); - - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); - - private class PolicyEnumerator : IEnumerator - { - private readonly IReadOnlyList _policies; - private int _current; - - public PolicyEnumerator(IReadOnlyList policies) - { - _policies = policies; - _current = -1; - } - - public PipelinePolicy Current - { - get - { - if (_current >= 0 && _current < _policies.Count) - { - return _policies[_current]; - } - - return null!; - } - } - - object IEnumerator.Current => Current; - - public bool MoveNext() => ++_current < _policies.Count; - - public void Reset() => _current = -1; - - public void Dispose() { } - } - } -} diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs deleted file mode 100644 index 6e5e8867a9c0..000000000000 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Adapter.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.ClientModel.Primitives; -using System.Net.Http; - -namespace Azure.Core.Pipeline -{ - public partial class HttpClientTransport - { - /// - /// Adds Azure.Core features to the System.ClientModel HttpClient-based transport. - /// - /// This type inherits from System.ClientModel's - /// and overrides the extensibility points for - /// and to add - /// features specific to Azure, such as . - /// - private class AzureCoreHttpPipelineTransport : HttpClientPipelineTransport - { - public AzureCoreHttpPipelineTransport(HttpClient client) : base(client) - { - } - - protected override PipelineMessage CreateMessageCore() - { - PipelineMessage message = base.CreateMessageCore(); - HttpClientTransportRequest request = new(message.Request); - return new HttpMessage(request, ResponseClassifier.Shared); - } - - /// - protected override void OnSendingRequest(PipelineMessage message, HttpRequestMessage httpRequest) - { - HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); - HttpClientTransportRequest.AddAzureProperties(httpMessage, httpRequest); - httpMessage.ClearResponse(); - } - - /// - protected override void OnReceivedResponse(PipelineMessage message, HttpResponseMessage httpResponse) - { - HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); - string clientRequestId = httpMessage.Request.ClientRequestId; - PipelineResponse pipelineResponse = message.Response!; - httpMessage.Response = new HttpClientTransportResponse(clientRequestId, pipelineResponse); - } - } - } -} diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs index 0780ed49d1f2..b90ae91508fd 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs @@ -11,19 +11,30 @@ namespace Azure.Core.Pipeline { - /// - /// An implementation that uses as the transport. - /// public partial class HttpClientTransport : HttpPipelineTransport, IDisposable { + /// + /// This is a transport-specific implementation of . + /// + /// It uses the System.ClientModel HttpClient-based transport + /// implementation and adapts + /// that transport's private nested HttpClientPipelineTransportRequest + /// type to the Azure.Core interface so that it + /// can reuse the ClientModel implementation but treat it as an + /// Azure.Core Request in Azure.Core-based clients. + /// private sealed class HttpClientTransportRequest : Request { // In this implementation of the abstract Azure.Core.Request type, - // we have two fields for each of the public properties -- one on the - // Request implementation and one in the PipelineRequest implementation. - // The implication of this is that we need to keep both sets of fields - // in sync with each other when they are set from either property on - // Request or PipelineRequest. + // ther are two fields for each of the public properties -- one on + // the base Request implementation and one in the adapted + // PipelineRequest implementation. Because of this, the + // implementation of this type is a bit complex in that we must + // keep both sets of fields in sync with each other when they are + // set from either property on Request or PipelineRequest, so they + // will have the same value regardless of whether they are accessed + // from the instance as a Azure.Core Request or as a + // System.ClientModel PipelineRequest. private readonly PipelineRequest _pipelineRequest; private string? _clientRequestId; @@ -32,7 +43,8 @@ public HttpClientTransportRequest(PipelineRequest request) { _pipelineRequest = request; - // Initialize duplicated properties on base type from adapted request. + // Initialize duplicated fields on the base instance + // from the adapted request instance. base.MethodCore = request.Method; base.ContentCore = request.Content; @@ -42,6 +54,8 @@ public HttpClientTransportRequest(PipelineRequest request) } } + #region Implement Azure.Core Request abstract methods + public override string ClientRequestId { get => _clientRequestId ??= Guid.NewGuid().ToString(); @@ -52,7 +66,32 @@ public override string ClientRequestId } } - #region Adapt PipelineResponse to inherit functional implementation from ClientModel + protected internal override void AddHeader(string name, string value) + => _pipelineRequest.Headers.Add(name, value); + + protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) + => _pipelineRequest.Headers.TryGetValue(name, out value); + + protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) + => _pipelineRequest.Headers.TryGetValues(name, out values); + + protected internal override bool ContainsHeader(string name) + => _pipelineRequest.Headers.TryGetValue(name, out _); + + protected internal override bool RemoveHeader(string name) + => _pipelineRequest.Headers.Remove(name); + + protected internal override IEnumerable EnumerateHeaders() + { + foreach (KeyValuePair header in _pipelineRequest.Headers) + { + yield return new HttpHeader(header.Key, header.Value); + } + } + + #endregion + + #region Overrides for "Core" methods from the PipelineRequest Template pattern protected override string MethodCore { @@ -101,34 +140,7 @@ protected override BinaryContent? ContentCore #endregion - #region Implement Azure.Core Request abstract methods - - protected internal override void AddHeader(string name, string value) - => _pipelineRequest.Headers.Add(name, value); - - protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) - => _pipelineRequest.Headers.TryGetValue(name, out value); - - protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) - => _pipelineRequest.Headers.TryGetValues(name, out values); - - protected internal override bool ContainsHeader(string name) - => _pipelineRequest.Headers.TryGetValue(name, out _); - - protected internal override bool RemoveHeader(string name) - => _pipelineRequest.Headers.Remove(name); - - protected internal override IEnumerable EnumerateHeaders() - { - foreach (KeyValuePair header in _pipelineRequest.Headers) - { - yield return new HttpHeader(header.Key, header.Value); - } - } - - #endregion - - #region Azure.Core extensions of ClientModel functionality + #region Azure.Core extensions of ClientModel HttpClientPipelineTransportRequest functionality private const string MessageForServerCertificateCallback = "MessageForServerCertificateCallback"; diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs index fed393a61548..4f3cf5000f8d 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Response.cs @@ -6,21 +6,27 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace Azure.Core.Pipeline { - /// - /// An implementation that uses as the transport. - /// public partial class HttpClientTransport : HttpPipelineTransport { + /// + /// This is a transport-specific implementation of . + /// + /// It uses the System.ClientModel HttpClient-based transport + /// implementation and adapts + /// that transport's private nested HttpClientPipelineTransportResponse + /// type to the Azure.Core interface so that it + /// can reuse the ClientModel implementation but treat it as an + /// Azure.Core Response in Azure.Core-based clients. + /// private sealed class HttpClientTransportResponse : Response { - private string _clientRequestId; private readonly PipelineResponse _pipelineResponse; + private string _clientRequestId; public HttpClientTransportResponse(string clientRequestId, PipelineResponse pipelineResponse) { @@ -57,7 +63,7 @@ public override BinaryData BufferContent(CancellationToken cancellationToken = d => _pipelineResponse.BufferContent(cancellationToken); public override async ValueTask BufferContentAsync(CancellationToken cancellationToken = default) - => await base.BufferContentAsync(cancellationToken).ConfigureAwait(false); + => await _pipelineResponse.BufferContentAsync(cancellationToken).ConfigureAwait(false); protected internal override bool ContainsHeader(string name) => _pipelineResponse.Headers.TryGetValue(name, out _); @@ -76,28 +82,30 @@ protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] o protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) => _pipelineResponse.Headers.TryGetValues(name, out values); + private static void ResetContentStreamPosition(PipelineResponse response) + { + if (response.ContentStream is MemoryStream && + response.ContentStream.CanSeek && + response.ContentStream.Position != 0) + { + // Azure.Core Response has a contract that ContentStream can + // be read without setting position back to 0. This means + // that if BufferContent is called after such a read, the + // buffer will contain empty BinaryData. + + // So that the ClientModel response implementations don't + // throw, we must set the position back to 0 if Azure.Core + // Response BufferContent was called. + response.ContentStream.Position = 0; + } + } + public override void Dispose() { PipelineResponse response = _pipelineResponse; ResetContentStreamPosition(response); response?.Dispose(); } - - private static void ResetContentStreamPosition(PipelineResponse response) - { - if (response.ContentStream is MemoryStream stream && response.ContentStream.CanSeek && - stream.Position != 0) - { - // Azure.Core Response has a contract that ContentStream can be read - // without setting position back to 0. This means if ReadContent is - // called after such a read, the buffer will contain empty BinaryData. - - // So that the ClientModel response implementations don't throw, - // set the position back to 0 if Azure.Core Response default - // ReadContent was called. - stream.Position = 0; - } - } } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs index 18c1bc678b32..5d740a82b488 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.cs @@ -3,6 +3,7 @@ using System; using System.ClientModel; +using System.ClientModel.Primitives; using System.Diagnostics; using System.Net; using System.Net.Http; @@ -14,7 +15,8 @@ namespace Azure.Core.Pipeline { /// - /// An implementation that uses as the transport. + /// An implementation that uses + /// as the transport. /// public partial class HttpClientTransport : HttpPipelineTransport, IDisposable { @@ -233,5 +235,48 @@ public void Dispose() GC.SuppressFinalize(this); } + + /// + /// Adds Azure.Core features to the System.ClientModel HttpClient-based + /// transport. + /// + /// This type inherits from System.ClientModel's + /// and overrides its + /// extensibility points for + /// + /// and + /// to add features specific to Azure, such as + /// . + /// + private class AzureCoreHttpPipelineTransport : HttpClientPipelineTransport + { + public AzureCoreHttpPipelineTransport(HttpClient client) : base(client) + { + } + + protected override PipelineMessage CreateMessageCore() + { + PipelineMessage message = base.CreateMessageCore(); + HttpClientTransportRequest request = new(message.Request); + return new HttpMessage(request, ResponseClassifier.Shared); + } + + /// + protected override void OnSendingRequest(PipelineMessage message, HttpRequestMessage httpRequest) + { + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message, "The provided message was created by a different transport."); + HttpClientTransportRequest.AddAzureProperties(httpMessage, httpRequest); + httpMessage.ClearResponse(); + } + + /// + protected override void OnReceivedResponse(PipelineMessage message, HttpResponseMessage httpResponse) + { + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message, "The provided message was created by a different transport."); + string clientRequestId = httpMessage.Request.ClientRequestId; + PipelineResponse pipelineResponse = message.Response!; + httpMessage.Response = new HttpClientTransportResponse(clientRequestId, pipelineResponse); + } + } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs index 0e5a37ed88e9..117e8a4547a5 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelinePolicy.cs @@ -3,6 +3,7 @@ using System; using System.ClientModel.Primitives; +using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; @@ -49,14 +50,7 @@ protected static void ProcessNext(HttpMessage message, ReadOnlyMemory - /// TBD. - /// - /// - /// - /// - /// - /// + /// public sealed override async ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList pipeline, int currentIndex) { if (message is not HttpMessage httpMessage) @@ -64,24 +58,20 @@ public sealed override async ValueTask ProcessAsync(PipelineMessage message, IRe throw new InvalidOperationException($"Invalid type for message: '{message?.GetType()}'"); } - if (pipeline is not AzureCorePipelineProcessor processor) + if (pipeline is not HttpPipelineAdapter processor) { throw new InvalidOperationException($"Invalid type for pipeline: '{pipeline?.GetType()}'"); } - // The contract across ClientModel policy and Azure.Core policy is different - // so if we're calling Process from a ClientModel policy, we need to pop some + // If this method is called, it means this method is being called + // from a System.ClientModel PipelinePolicy instance. Since the + // contract for the pipeline parameter for Azure.Core and + // ClientModel Process methods is different, we need to pop some // policies off the stack before calling Process on the Azure.Core policy. await ProcessAsync(httpMessage, processor.Policies.Slice(currentIndex + 1)).ConfigureAwait(false); } - /// - /// TBD. - /// - /// - /// - /// - /// + /// public sealed override void Process(PipelineMessage message, IReadOnlyList pipeline, int currentIndex) { if (message is not HttpMessage httpMessage) @@ -89,12 +79,101 @@ public sealed override void Process(PipelineMessage message, IReadOnlyList + /// This type adapts the policy collection in Azure.Core's + /// , which is of type + /// , to the + /// System.ClientModel policy collection, which is of type + /// . + /// + /// This allows Azure.Core instances + /// to be called from the System.ClientModel . + /// This is because System.ClientModel policies of type + /// will pass the policy collection as an + /// instance of . In order for + /// Azure.Core policies to pass control to the next policy in the + /// collection, they must be able to pass the collection as a + /// . The underlying + /// used to implement the + /// is exposed on this type as + /// property. + /// + /// In addition, this type also allows Azure.Core policies such as + /// to hold System.ClientModel policies as + /// private members and call their + /// + /// methods to use the ClientModel functionality and also continue passing + /// control down the chain of policies, across both + /// and types. + /// + internal struct HttpPipelineAdapter : IReadOnlyList + { + private readonly ReadOnlyMemory _policies; + private PolicyEnumerator? _enumerator; + + public HttpPipelineAdapter(ReadOnlyMemory policies) + { + _policies = policies; + } + + public ReadOnlyMemory Policies + => _policies; + + public PipelinePolicy this[int index] => _policies.Span[index]; + + public int Count => _policies.Length; + + public IEnumerator GetEnumerator() + => _enumerator ??= new(this); + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + private class PolicyEnumerator : IEnumerator + { + private readonly IReadOnlyList _policies; + private int _current; + + public PolicyEnumerator(IReadOnlyList policies) + { + _policies = policies; + _current = -1; + } + + public PipelinePolicy Current + { + get + { + if (_current >= 0 && _current < _policies.Count) + { + return _policies[_current]; + } + + return null!; + } + } + + object IEnumerator.Current => Current; + + public bool MoveNext() => ++_current < _policies.Count; + + public void Reset() => _current = -1; + + public void Dispose() { } + } + } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs deleted file mode 100644 index 814ffc00431a..000000000000 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.Adapter.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.ClientModel.Primitives; -using System.Threading.Tasks; - -namespace Azure.Core.Pipeline; - -public partial class HttpPipelineTransport -{ - private class AzureCorePipelineTransport : PipelineTransport - { - private readonly HttpPipelineTransport _transport; - - public AzureCorePipelineTransport(HttpPipelineTransport transport) - { - _transport = transport; - } - - protected override PipelineMessage CreateMessageCore() - { - Request request = _transport.CreateRequest(); - return new HttpMessage(request, ResponseClassifier.Shared); - } - - protected override void ProcessCore(PipelineMessage message) - { - HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); - _transport.Process(httpMessage); - } - - protected override async ValueTask ProcessCoreAsync(PipelineMessage message) - { - HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); - await _transport.ProcessAsync(httpMessage).ConfigureAwait(false); - } - } -} diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.cs b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.cs index c372a13d072a..6811e74a318a 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpPipelineTransport.cs @@ -9,28 +9,8 @@ namespace Azure.Core.Pipeline /// /// Represents an HTTP pipeline transport used to send HTTP requests and receive responses. /// - public abstract partial class HttpPipelineTransport + public abstract class HttpPipelineTransport : PipelineTransport { - private readonly PipelineTransport _transport; - - /// - /// TBD. - /// - protected HttpPipelineTransport() - { - _transport = new AzureCorePipelineTransport(this); - } - - internal void ProcessInternal(HttpMessage message) - { - _transport.Process(message); - } - - internal async ValueTask ProcessInternalAsync(HttpMessage message) - { - await _transport.ProcessAsync(message).ConfigureAwait(false); - } - /// /// Sends the request contained by the and sets the property to received response synchronously. /// @@ -50,6 +30,24 @@ internal async ValueTask ProcessInternalAsync(HttpMessage message) /// public abstract Request CreateRequest(); + /// + protected sealed override PipelineMessage CreateMessageCore() + => new HttpMessage(CreateRequest(), ResponseClassifier.Shared); + + /// + protected sealed override void ProcessCore(PipelineMessage message) + { + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message, "The provided message was created by a different transport."); + Process(httpMessage); + } + + /// + protected sealed override async ValueTask ProcessCoreAsync(PipelineMessage message) + { + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message, "The provided message was created by a different transport."); + await ProcessAsync(httpMessage).ConfigureAwait(false); + } + /// /// Creates the default based on the current environment and configuration. /// diff --git a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs index e2152809a849..0f9f27b68af8 100644 --- a/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/Internal/HttpPipelineTransportPolicy.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ClientModel.Primitives; using System.Diagnostics; using System.Threading.Tasks; @@ -24,22 +25,20 @@ public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory { Debug.Assert(pipeline.IsEmpty); - await _transport.ProcessInternalAsync(message).ConfigureAwait(false); + await _transport.ProcessAsync(message as PipelineMessage).ConfigureAwait(false); message.Response.RequestFailedDetailsParser = _errorParser; message.Response.Sanitizer = _sanitizer; - message.Response.SetIsError(message.ResponseClassifier.IsErrorResponse(message)); } public override void Process(HttpMessage message, ReadOnlyMemory pipeline) { Debug.Assert(pipeline.IsEmpty); - _transport.ProcessInternal(message); + _transport.Process(message as PipelineMessage); message.Response.RequestFailedDetailsParser = _errorParser; message.Response.Sanitizer = _sanitizer; - message.Response.SetIsError(message.ResponseClassifier.IsErrorResponse(message)); } } } diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs index b1873a04c6a5..057ddc7957a5 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs @@ -53,17 +53,17 @@ public override void Process(HttpMessage message, ReadOnlyMemory pipeline, bool async) { - AzureCorePipelineProcessor processor = new(pipeline); + HttpPipelineAdapter httpPipeline = new(pipeline); try { if (async) { - await _policy.ProcessAsync(message, processor, -1).ConfigureAwait(false); + await _policy.ProcessAsync(message, httpPipeline, -1).ConfigureAwait(false); } else { - _policy.Process(message, processor, -1); + _policy.Process(message, httpPipeline, -1); } } catch (AggregateException e) From 8ec76d28292db81f1aa4e627cdc27f5fe207b563 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 1 Mar 2024 09:05:46 -0800 Subject: [PATCH 43/47] export API --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 5 ++++- sdk/core/Azure.Core/api/Azure.Core.net472.cs | 5 ++++- sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 5 ++++- sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index 7441102480a5..df00724eacf0 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -1059,12 +1059,15 @@ public virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } - public abstract partial class HttpPipelineTransport + public abstract partial class HttpPipelineTransport : System.ClientModel.Primitives.PipelineTransport { protected HttpPipelineTransport() { } + protected sealed override System.ClientModel.Primitives.PipelineMessage CreateMessageCore() { throw null; } public abstract Azure.Core.Request CreateRequest(); public abstract void Process(Azure.Core.HttpMessage message); public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message); + protected sealed override void ProcessCore(System.ClientModel.Primitives.PipelineMessage message) { } + protected sealed override System.Threading.Tasks.ValueTask ProcessCoreAsync(System.ClientModel.Primitives.PipelineMessage message) { throw null; } } public partial class HttpPipelineTransportOptions { diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index 7441102480a5..df00724eacf0 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -1059,12 +1059,15 @@ public virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } - public abstract partial class HttpPipelineTransport + public abstract partial class HttpPipelineTransport : System.ClientModel.Primitives.PipelineTransport { protected HttpPipelineTransport() { } + protected sealed override System.ClientModel.Primitives.PipelineMessage CreateMessageCore() { throw null; } public abstract Azure.Core.Request CreateRequest(); public abstract void Process(Azure.Core.HttpMessage message); public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message); + protected sealed override void ProcessCore(System.ClientModel.Primitives.PipelineMessage message) { } + protected sealed override System.Threading.Tasks.ValueTask ProcessCoreAsync(System.ClientModel.Primitives.PipelineMessage message) { throw null; } } public partial class HttpPipelineTransportOptions { diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index 6a406d4246c8..cba1deb9e384 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -1064,12 +1064,15 @@ public virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } - public abstract partial class HttpPipelineTransport + public abstract partial class HttpPipelineTransport : System.ClientModel.Primitives.PipelineTransport { protected HttpPipelineTransport() { } + protected sealed override System.ClientModel.Primitives.PipelineMessage CreateMessageCore() { throw null; } public abstract Azure.Core.Request CreateRequest(); public abstract void Process(Azure.Core.HttpMessage message); public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message); + protected sealed override void ProcessCore(System.ClientModel.Primitives.PipelineMessage message) { } + protected sealed override System.Threading.Tasks.ValueTask ProcessCoreAsync(System.ClientModel.Primitives.PipelineMessage message) { throw null; } } public partial class HttpPipelineTransportOptions { diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index 7441102480a5..df00724eacf0 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -1059,12 +1059,15 @@ public virtual void OnSendingRequest(Azure.Core.HttpMessage message) { } public override void Process(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { } public override System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message, System.ReadOnlyMemory pipeline) { throw null; } } - public abstract partial class HttpPipelineTransport + public abstract partial class HttpPipelineTransport : System.ClientModel.Primitives.PipelineTransport { protected HttpPipelineTransport() { } + protected sealed override System.ClientModel.Primitives.PipelineMessage CreateMessageCore() { throw null; } public abstract Azure.Core.Request CreateRequest(); public abstract void Process(Azure.Core.HttpMessage message); public abstract System.Threading.Tasks.ValueTask ProcessAsync(Azure.Core.HttpMessage message); + protected sealed override void ProcessCore(System.ClientModel.Primitives.PipelineMessage message) { } + protected sealed override System.Threading.Tasks.ValueTask ProcessCoreAsync(System.ClientModel.Primitives.PipelineMessage message) { throw null; } } public partial class HttpPipelineTransportOptions { From d73e12b88a16aa8dd37846edb288ba10cea2b558 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 1 Mar 2024 13:18:26 -0800 Subject: [PATCH 44/47] updates from #42294 --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 2 +- sdk/core/Azure.Core/api/Azure.Core.net472.cs | 2 +- sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 2 +- .../api/Azure.Core.netstandard2.0.cs | 2 +- .../Pipeline/HttpClientTransport.Request.cs | 15 ++++++++----- .../Pipeline/RequestFailedDetailsParser.cs | 3 ++- .../Azure.Core/src/RequestFailedException.cs | 22 +++++++++++++------ 7 files changed, 30 insertions(+), 18 deletions(-) diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index df00724eacf0..baf038cd560c 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -234,7 +234,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? detailsParser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index df00724eacf0..baf038cd560c 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -234,7 +234,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? detailsParser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index cba1deb9e384..ba64fc5d4173 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -234,7 +234,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? detailsParser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index df00724eacf0..baf038cd560c 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -234,7 +234,7 @@ public partial class RequestFailedException : System.ClientModel.ClientResultExc public RequestFailedException(string message) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public RequestFailedException(string message, System.Exception? innerException) : base (default(System.ClientModel.Primitives.PipelineResponse), default(System.Exception)) { } public string? ErrorCode { get { throw null; } } - public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? parser = null, System.Exception? innerException = null) { throw null; } + public static System.Threading.Tasks.ValueTask CreateAsync(Azure.Response response, Azure.Core.RequestFailedDetailsParser? detailsParser = null, System.Exception? innerException = null) { throw null; } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public new Azure.Response? GetRawResponse() { throw null; } } diff --git a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs index b90ae91508fd..38ec2319f7e4 100644 --- a/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs +++ b/sdk/core/Azure.Core/src/Pipeline/HttpClientTransport.Request.cs @@ -69,18 +69,21 @@ public override string ClientRequestId protected internal override void AddHeader(string name, string value) => _pipelineRequest.Headers.Add(name, value); - protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) - => _pipelineRequest.Headers.TryGetValue(name, out value); - - protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) - => _pipelineRequest.Headers.TryGetValues(name, out values); - protected internal override bool ContainsHeader(string name) => _pipelineRequest.Headers.TryGetValue(name, out _); protected internal override bool RemoveHeader(string name) => _pipelineRequest.Headers.Remove(name); + protected internal override void SetHeader(string name, string value) + => _pipelineRequest.Headers.Set(name, value); + + protected internal override bool TryGetHeader(string name, [NotNullWhen(true)] out string? value) + => _pipelineRequest.Headers.TryGetValue(name, out value); + + protected internal override bool TryGetHeaderValues(string name, [NotNullWhen(true)] out IEnumerable? values) + => _pipelineRequest.Headers.TryGetValues(name, out values); + protected internal override IEnumerable EnumerateHeaders() { foreach (KeyValuePair header in _pipelineRequest.Headers) diff --git a/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs b/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs index b30790a7ce5c..e30529353306 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RequestFailedDetailsParser.cs @@ -15,7 +15,8 @@ public abstract class RequestFailedDetailsParser /// /// Parses the error details from the provided . /// - /// The to parse. The will already be buffered. + /// The to parse. The + /// will already be buffered. /// The describing the parsed error details. /// Data to be applied to the property. /// true if successful, otherwise false. diff --git a/sdk/core/Azure.Core/src/RequestFailedException.cs b/sdk/core/Azure.Core/src/RequestFailedException.cs index 33fdb99fc3e9..3ab763da0241 100644 --- a/sdk/core/Azure.Core/src/RequestFailedException.cs +++ b/sdk/core/Azure.Core/src/RequestFailedException.cs @@ -23,15 +23,23 @@ public class RequestFailedException : ClientResultException, ISerializable private const string DefaultMessage = "Service request failed."; /// - /// TBD. + /// Creates an instance of in an + /// async context. /// - /// - /// - /// - /// - public static async ValueTask CreateAsync(Response response, RequestFailedDetailsParser? parser = default, Exception? innerException = default) + /// The to obtain error + /// details from. + /// The parser to use to parse the response + /// content. + /// An inner exception to associate with + /// the new . + /// The that was created. + /// + public static async ValueTask CreateAsync( + Response response, + RequestFailedDetailsParser? detailsParser = default, + Exception? innerException = default) { - ErrorDetails details = await CreateExceptionDetailsAsync(response, parser).ConfigureAwait(false); + ErrorDetails details = await CreateExceptionDetailsAsync(response, detailsParser).ConfigureAwait(false); return new RequestFailedException(response, details, innerException); } From d3cc683acdd5c22e130d2c78a1188541bb4e0afd Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 1 Mar 2024 13:30:58 -0800 Subject: [PATCH 45/47] Remove serialization constructor from ClientResultException --- .../Azure.Core/src/RequestFailedException.cs | 5 ++++- sdk/core/System.ClientModel/CHANGELOG.md | 19 ++++++++++++++--- .../api/System.ClientModel.net6.0.cs | 4 +--- .../api/System.ClientModel.netstandard2.0.cs | 4 +--- .../src/Convenience/ClientResultException.cs | 21 +------------------ .../src/System.ClientModel.csproj | 2 +- 6 files changed, 24 insertions(+), 31 deletions(-) diff --git a/sdk/core/Azure.Core/src/RequestFailedException.cs b/sdk/core/Azure.Core/src/RequestFailedException.cs index 3ab763da0241..26e2e9c6b8e9 100644 --- a/sdk/core/Azure.Core/src/RequestFailedException.cs +++ b/sdk/core/Azure.Core/src/RequestFailedException.cs @@ -146,9 +146,11 @@ public RequestFailedException(int status, string message, string? errorCode, Exc #region ISerializable implementation /// + // TODO protected RequestFailedException(SerializationInfo info, StreamingContext context) - : base(info, context) + : base("Serialization constructor must be added to ClientResultException.") { + Status = info.GetInt32(nameof(Status)); ErrorCode = info.GetString(nameof(ErrorCode)); } @@ -157,6 +159,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont { Argument.AssertNotNull(info, nameof(info)); + info.AddValue(nameof(Status), Status); info.AddValue(nameof(ErrorCode), ErrorCode); base.GetObjectData(info, context); diff --git a/sdk/core/System.ClientModel/CHANGELOG.md b/sdk/core/System.ClientModel/CHANGELOG.md index c589a2772e91..3111f298b5a8 100644 --- a/sdk/core/System.ClientModel/CHANGELOG.md +++ b/sdk/core/System.ClientModel/CHANGELOG.md @@ -1,16 +1,29 @@ # Release History -## 1.1.0-beta.2 (Unreleased) +## 1.1.0-beta.3 (Unreleased) + +### Features Added + +### Breaking Changes + +### Bugs Fixed + +### Other Changes + +## 1.1.0-beta.2 (2024-02-29) ### Features Added - Added `ExtractResponse` method to `PipelineMessage` to enable returning an undisposed `PipelineResponse` from protocol methods. +- Added `CreateAsync` factory method to `ClientResultException` to allow creating exceptions in an async context. +- Added an implicit cast from `string` to `ApiKeyCredential`. +- Added an implicit cast from `ClientResult` to `T`. ### Breaking Changes - Changed `HttpClientPipelineTransport.Shared` and `ClientRetryPolicy.Default` from static readonly fields to static properties. - -### Bugs Fixed +- Changed `PipelineResponse.Content` property from abstract to virtual. +- Removed the `ResponseBufferingPolicy` and moved response buffering functionality into `PipelineTransport`. ### Other Changes diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs index 0756eb961907..5b25ab68714a 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs @@ -25,14 +25,12 @@ protected ClientResult(System.ClientModel.Primitives.PipelineResponse response) public static System.ClientModel.ClientResult FromValue(T value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public System.ClientModel.Primitives.PipelineResponse GetRawResponse() { throw null; } } - public partial class ClientResultException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class ClientResultException : System.Exception { public ClientResultException(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { } - protected ClientResultException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public ClientResultException(string message, System.ClientModel.Primitives.PipelineResponse? response = null, System.Exception? innerException = null) { } public int Status { get { throw null; } protected set { } } public static System.Threading.Tasks.Task CreateAsync(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { throw null; } - public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public System.ClientModel.Primitives.PipelineResponse? GetRawResponse() { throw null; } } public partial class ClientResult : System.ClientModel.ClientResult diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs index d6220b4a1441..77fe988d4326 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs @@ -25,14 +25,12 @@ protected ClientResult(System.ClientModel.Primitives.PipelineResponse response) public static System.ClientModel.ClientResult FromValue(T value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public System.ClientModel.Primitives.PipelineResponse GetRawResponse() { throw null; } } - public partial class ClientResultException : System.Exception, System.Runtime.Serialization.ISerializable + public partial class ClientResultException : System.Exception { public ClientResultException(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { } - protected ClientResultException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public ClientResultException(string message, System.ClientModel.Primitives.PipelineResponse? response = null, System.Exception? innerException = null) { } public int Status { get { throw null; } protected set { } } public static System.Threading.Tasks.Task CreateAsync(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { throw null; } - public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public System.ClientModel.Primitives.PipelineResponse? GetRawResponse() { throw null; } } public partial class ClientResult : System.ClientModel.ClientResult diff --git a/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs b/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs index f64c10d1b5b7..15356c161c7d 100644 --- a/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs +++ b/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs @@ -4,7 +4,6 @@ using System.ClientModel.Internal; using System.ClientModel.Primitives; using System.Globalization; -using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; @@ -13,8 +12,7 @@ namespace System.ClientModel; /// /// The exception that is thrown when the processing of a client request failed. /// -[Serializable] -public class ClientResultException : Exception, ISerializable +public class ClientResultException : Exception { private const string DefaultMessage = "Service request failed."; @@ -84,23 +82,6 @@ public ClientResultException(string message, PipelineResponse? response = defaul _status = response?.Status ?? 0; } - /// - protected ClientResultException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - _status = info.GetInt32(nameof(Status)); - } - - /// - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - Argument.AssertNotNull(info, nameof(info)); - - info.AddValue(nameof(Status), Status); - - base.GetObjectData(info, context); - } - /// /// Gets the , if any, that led to the exception. /// diff --git a/sdk/core/System.ClientModel/src/System.ClientModel.csproj b/sdk/core/System.ClientModel/src/System.ClientModel.csproj index 3d19c5096bdd..3a6bfc245bc2 100644 --- a/sdk/core/System.ClientModel/src/System.ClientModel.csproj +++ b/sdk/core/System.ClientModel/src/System.ClientModel.csproj @@ -2,7 +2,7 @@ Contains building blocks for clients that call cloud services. - 1.1.0-beta.2 + 1.1.0-beta.3 1.0.0 enable From 20bd68a6ab03cdf0c14dc2616118e5994e359992 Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Fri, 1 Mar 2024 16:17:06 -0800 Subject: [PATCH 46/47] Remove ClientOptions inheritance; keep in sync with #42329 --- sdk/core/Azure.Core/api/Azure.Core.net461.cs | 8 +- sdk/core/Azure.Core/api/Azure.Core.net472.cs | 8 +- sdk/core/Azure.Core/api/Azure.Core.net6.0.cs | 8 +- .../api/Azure.Core.netstandard2.0.cs | 8 +- sdk/core/Azure.Core/src/Azure.Core.csproj | 1 - sdk/core/Azure.Core/src/ClientOptions.cs | 33 +--- sdk/core/Azure.Core/src/DiagnosticsOptions.cs | 95 +--------- .../Azure.Core/src/Internal/BitVector640.cs | 165 ++++++++++++++++++ .../src/Pipeline/RetryPolicy.Adapter.cs | 99 ----------- .../Azure.Core/src/Pipeline/RetryPolicy.cs | 159 +++++++++++++++-- .../Azure.Core/src/RequestFailedException.cs | 5 +- sdk/core/Azure.Core/src/RetryOptions.cs | 77 +------- .../src/Shared/CancellationHelper.cs | 2 +- .../Azure.Core/src/StatusCodeClassifier.cs | 2 +- .../api/System.ClientModel.net6.0.cs | 6 +- .../api/System.ClientModel.netstandard2.0.cs | 6 +- .../src/Convenience/ClientResultException.cs | 21 ++- .../src/Internal/ArrayBackedPropertyBag.cs | 34 ++-- .../src/Message/ArrayBackedRequestHeaders.cs | 15 +- .../src/Message/PipelineMessage.cs | 2 +- .../HttpClientPipelineTransport.Request.cs | 2 +- 21 files changed, 395 insertions(+), 361 deletions(-) create mode 100644 sdk/core/Azure.Core/src/Internal/BitVector640.cs delete mode 100644 sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs diff --git a/sdk/core/Azure.Core/api/Azure.Core.net461.cs b/sdk/core/Azure.Core/api/Azure.Core.net461.cs index baf038cd560c..546bf228f884 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net461.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net461.cs @@ -382,19 +382,18 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions + public abstract partial class ClientOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } - public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -740,7 +739,6 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier diff --git a/sdk/core/Azure.Core/api/Azure.Core.net472.cs b/sdk/core/Azure.Core/api/Azure.Core.net472.cs index baf038cd560c..546bf228f884 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net472.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net472.cs @@ -382,19 +382,18 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions + public abstract partial class ClientOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } - public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -740,7 +739,6 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index ba64fc5d4173..7d724a8c6f1e 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -382,19 +382,18 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions + public abstract partial class ClientOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } - public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -743,7 +742,6 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier diff --git a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs index baf038cd560c..546bf228f884 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs @@ -382,19 +382,18 @@ public partial struct AccessToken public static bool operator !=(Azure.Core.AzureLocation left, Azure.Core.AzureLocation right) { throw null; } public override string ToString() { throw null; } } - public abstract partial class ClientOptions : System.ClientModel.Primitives.ClientPipelineOptions + public abstract partial class ClientOptions { protected ClientOptions() { } protected ClientOptions(Azure.Core.DiagnosticsOptions? diagnostics) { } public static Azure.Core.ClientOptions Default { get { throw null; } } public Azure.Core.DiagnosticsOptions Diagnostics { get { throw null; } } public Azure.Core.RetryOptions Retry { get { throw null; } } - public new Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } - public new Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelinePolicy? RetryPolicy { get { throw null; } set { } } + public Azure.Core.Pipeline.HttpPipelineTransport Transport { get { throw null; } set { } } public void AddPolicy(Azure.Core.Pipeline.HttpPipelinePolicy policy, Azure.Core.HttpPipelinePosition position) { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object? obj) { throw null; } - public override void Freeze() { } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override int GetHashCode() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] @@ -740,7 +739,6 @@ internal RetryOptions() { } public System.TimeSpan MaxDelay { get { throw null; } set { } } public int MaxRetries { get { throw null; } set { } } public Azure.Core.RetryMode Mode { get { throw null; } set { } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public System.TimeSpan NetworkTimeout { get { throw null; } set { } } } public partial class StatusCodeClassifier : Azure.Core.ResponseClassifier diff --git a/sdk/core/Azure.Core/src/Azure.Core.csproj b/sdk/core/Azure.Core/src/Azure.Core.csproj index 3d12d5114b46..663ad6405b8f 100644 --- a/sdk/core/Azure.Core/src/Azure.Core.csproj +++ b/sdk/core/Azure.Core/src/Azure.Core.csproj @@ -73,7 +73,6 @@ - diff --git a/sdk/core/Azure.Core/src/ClientOptions.cs b/sdk/core/Azure.Core/src/ClientOptions.cs index b4f46998b138..45b34778af00 100644 --- a/sdk/core/Azure.Core/src/ClientOptions.cs +++ b/sdk/core/Azure.Core/src/ClientOptions.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using System.ClientModel.Primitives; using System.Collections.Generic; using System.ComponentModel; using Azure.Core.Pipeline; @@ -12,15 +11,13 @@ namespace Azure.Core /// /// Base type for all client option types, exposes various common client options like , , . /// - public abstract class ClientOptions : ClientPipelineOptions + public abstract class ClientOptions { internal static readonly TimeSpan DefaultNetworkTimeout = TimeSpan.FromSeconds(100); private HttpPipelineTransport _transport; internal bool IsCustomTransportSet { get; private set; } - private HttpPipelinePolicy? _retryPolicy; - /// /// Gets the default set of . Changes to the options would be reflected /// in new instances of type created after changes to were made. @@ -76,13 +73,11 @@ internal ClientOptions(ClientOptions? clientOptions, DiagnosticsOptions? diagnos /// /// The to be used for this client. Defaults to an instance of . /// - public new HttpPipelineTransport Transport + public HttpPipelineTransport Transport { get => _transport; set { - AssertNotFrozen(); - _transport = value ?? throw new ArgumentNullException(nameof(value)); IsCustomTransportSet = true; } @@ -104,16 +99,7 @@ internal ClientOptions(ClientOptions? clientOptions, DiagnosticsOptions? diagnos /// If is overridden or a custom is specified, /// it is the implementer's responsibility to update the values. /// - public new HttpPipelinePolicy? RetryPolicy - { - get => _retryPolicy; - set - { - AssertNotFrozen(); - - _retryPolicy = value; - } - } + public HttpPipelinePolicy? RetryPolicy { get; set; } /// /// Adds an policy into the client pipeline. The position of policy in the pipeline is controlled by the parameter. @@ -124,8 +110,6 @@ internal ClientOptions(ClientOptions? clientOptions, DiagnosticsOptions? diagnos /// The position of policy in the pipeline. public void AddPolicy(HttpPipelinePolicy policy, HttpPipelinePosition position) { - AssertNotFrozen(); - if (position != HttpPipelinePosition.PerCall && position != HttpPipelinePosition.PerRetry && position != HttpPipelinePosition.BeforeTransport) @@ -150,16 +134,5 @@ public void AddPolicy(HttpPipelinePolicy policy, HttpPipelinePosition position) /// [EditorBrowsable(EditorBrowsableState.Never)] public override string? ToString() => base.ToString(); - - /// - /// TBD. - /// - public override void Freeze() - { - Diagnostics.Freeze(); - Retry.Freeze(); - - base.Freeze(); - } } } diff --git a/sdk/core/Azure.Core/src/DiagnosticsOptions.cs b/sdk/core/Azure.Core/src/DiagnosticsOptions.cs index afd5c48172cd..bfec3b23b5da 100644 --- a/sdk/core/Azure.Core/src/DiagnosticsOptions.cs +++ b/sdk/core/Azure.Core/src/DiagnosticsOptions.cs @@ -16,20 +16,11 @@ public class DiagnosticsOptions private string? _applicationId; - private bool _isLoggingEnabled = true; - private bool _isDistributedTracingEnabled = true; - private bool _isTelemetryEnabled; - private bool _isLoggingContentEnabled; - private int _loggedContentSizeLimit = 4 * 1024; - - private bool _frozen; - /// /// Creates a new instance of with default values. /// protected internal DiagnosticsOptions() : this(ClientOptions.Default.Diagnostics) - { - } + { } /// /// Initializes the newly created with the same settings as the specified . @@ -87,84 +78,39 @@ internal DiagnosticsOptions(DiagnosticsOptions? diagnosticsOptions) /// /// Get or sets value indicating whether HTTP pipeline logging is enabled. /// - public bool IsLoggingEnabled - { - get => _isLoggingEnabled; - set - { - AssertNotFrozen(); - - _isLoggingEnabled = value; - } - } + public bool IsLoggingEnabled { get; set; } = true; /// /// Gets or sets value indicating whether distributed tracing activities () are going to be created for the clients methods calls and HTTP calls. /// - public bool IsDistributedTracingEnabled - { - get => _isDistributedTracingEnabled; - set - { - AssertNotFrozen(); - - _isDistributedTracingEnabled = value; - } - } + 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 => _isTelemetryEnabled; - set - { - AssertNotFrozen(); - - _isTelemetryEnabled = value; - } - } + public bool IsTelemetryEnabled { get; set; } /// /// Gets or sets value indicating if request or response content should be logged. /// - public bool IsLoggingContentEnabled - { - get => _isLoggingContentEnabled; - set - { - AssertNotFrozen(); - - _isLoggingContentEnabled = value; - } - } + public bool IsLoggingContentEnabled { get; set; } /// /// Gets or sets value indicating maximum size of content to log in bytes. Defaults to 4096. /// - public int LoggedContentSizeLimit - { - get => _loggedContentSizeLimit; - set - { - AssertNotFrozen(); - - _loggedContentSizeLimit = value; - } - } + public int LoggedContentSizeLimit { get; set; } = 4 * 1024; /// /// Gets a list of header names that are not redacted during logging. /// - public IList LoggedHeaderNames { get; private set; } + public IList LoggedHeaderNames { get; internal set; } /// /// Gets a list of query parameter names that are not redacted during logging. /// - public IList LoggedQueryParameters { get; private set; } + public IList LoggedQueryParameters { get; internal set; } /// /// Gets or sets the value sent as the first part of "User-Agent" headers for all requests issues by this client. Defaults to . @@ -174,8 +120,6 @@ public string? ApplicationId get => _applicationId; set { - AssertNotFrozen(); - if (value != null && value.Length > MaxApplicationIdLength) { throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(ApplicationId)} must be shorter than {MaxApplicationIdLength + 1} characters"); @@ -209,28 +153,5 @@ public static string? DefaultApplicationId return null; } - - internal void Freeze() - { - _frozen = true; - - if (LoggedHeaderNames is List mutableHeaderNames) - { - LoggedHeaderNames = mutableHeaderNames.AsReadOnly(); - } - - if (LoggedQueryParameters is List mutableQueryParameters) - { - LoggedQueryParameters = mutableQueryParameters.AsReadOnly(); - } - } - - private void AssertNotFrozen() - { - if (_frozen) - { - throw new InvalidOperationException("Cannot change a ClientOptions instance after it has been used to create a client."); - } - } } } diff --git a/sdk/core/Azure.Core/src/Internal/BitVector640.cs b/sdk/core/Azure.Core/src/Internal/BitVector640.cs new file mode 100644 index 000000000000..6994d9e235a3 --- /dev/null +++ b/sdk/core/Azure.Core/src/Internal/BitVector640.cs @@ -0,0 +1,165 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.Core.Internal; + +/// +/// This type effectively stores 640 bool values, but compresses their storage +/// into ten ulongs, where each bit of the ulong represents a single bool value. +/// +/// It exposes a public indexer so that the bool values can be accessed as a +/// standard .NET collection API. +/// +/// It is used in System.ClientModel and Azure.Core to implement response +/// classifiers, where each true bit represents a status code that the +/// classifier considers a success code. +/// +internal struct BitVector640 +{ + // Keeping ulongs as fields puts them on the stack. + private ulong _bits0; + private ulong _bits1; + private ulong _bits2; + private ulong _bits3; + private ulong _bits4; + private ulong _bits5; + private ulong _bits6; + private ulong _bits7; + private ulong _bits8; + private ulong _bits9; + + public bool this[int i] + { + readonly get + { + // "Index" of the ulong the bit is stored in. + int index = i >> 6; + + // i % 6, i.e. the offset of the bit in the ulong. + int mod = i & 0b111111; + + // A mask that lets us access the single bit + ulong mask = 1ul << mod; + + // The storage ulong and the mask + ulong bit = Get(index) & mask; + + // If the bit equals the mask, the bit was set to true. + return bit == mask; + } + set + { + // "Index" of the ulong the bit is stored in. + int index = i >> 6; + + // i % 6, i.e. the offset of the bit in the ulong. + int mod = i & 0b111111; + + // A mask that lets us access the single bit + ulong mask = 1ul << mod; + + // Set the bit in question to the passed-in value + Set(index, mask, value); + } + } + + private readonly ulong Get(int index) + { + return index switch + { + 0 => _bits0, + 1 => _bits1, + 2 => _bits2, + 3 => _bits3, + 4 => _bits4, + 5 => _bits5, + 6 => _bits6, + 7 => _bits7, + 8 => _bits8, + 9 => _bits9, + _ => throw new InvalidOperationException(), + }; + } + + private void Set(int index, ulong mask, bool value) + { + if (value) + { + switch (index) + { + case 0: + _bits0 |= mask; + break; + case 1: + _bits1 |= mask; + break; + case 2: + _bits2 |= mask; + break; + case 3: + _bits3 |= mask; + break; + case 4: + _bits4 |= mask; + break; + case 5: + _bits5 |= mask; + break; + case 6: + _bits6 |= mask; + break; + case 7: + _bits7 |= mask; + break; + case 8: + _bits8 |= mask; + break; + case 9: + _bits9 |= mask; + break; + default: + throw new InvalidOperationException(); + } + } + else + { + switch (index) + { + case 0: + _bits0 &= ~mask; + break; + case 1: + _bits1 &= ~mask; + break; + case 2: + _bits2 &= ~mask; + break; + case 3: + _bits3 &= ~mask; + break; + case 4: + _bits4 &= ~mask; + break; + case 5: + _bits5 &= ~mask; + break; + case 6: + _bits6 &= ~mask; + break; + case 7: + _bits7 &= ~mask; + break; + case 8: + _bits8 &= ~mask; + break; + case 9: + _bits9 &= ~mask; + break; + default: + throw new InvalidOperationException(); + } + } + } +} diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs deleted file mode 100644 index 92c9a1a2722a..000000000000 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.Adapter.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.ClientModel.Primitives; -using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -using Azure.Core.Diagnostics; - -namespace Azure.Core.Pipeline; - -public partial class RetryPolicy -{ - /// - /// Adds Azure.Core features to the System.ClientModel retry policy. - /// - internal class AzureCoreRetryPolicy : ClientRetryPolicy - { - private readonly RetryPolicy _pipelinePolicy; - private readonly DelayStrategy _delayStrategy; - - private long _beforeProcess; - private long _afterProcess; - private double _elapsedTime; - - public AzureCoreRetryPolicy(int maxRetries, DelayStrategy delay, RetryPolicy policy) - : base(maxRetries) - { - _delayStrategy = delay; - _pipelinePolicy = policy; - } - - protected override void OnSendingRequest(PipelineMessage message) - { - _beforeProcess = Stopwatch.GetTimestamp(); - - _pipelinePolicy.OnSendingRequest(HttpMessage.GetHttpMessage(message)); - } - - protected override async ValueTask OnSendingRequestAsync(PipelineMessage message) - { - _beforeProcess = Stopwatch.GetTimestamp(); - - await _pipelinePolicy.OnSendingRequestAsync(HttpMessage.GetHttpMessage(message)).ConfigureAwait(false); - } - - protected override void OnRequestSent(PipelineMessage message) - { - _pipelinePolicy.OnRequestSent(HttpMessage.GetHttpMessage(message)); - - _afterProcess = Stopwatch.GetTimestamp(); - _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; - } - - protected override async ValueTask OnRequestSentAsync(PipelineMessage message) - { - await _pipelinePolicy.OnRequestSentAsync(HttpMessage.GetHttpMessage(message)).ConfigureAwait(false); - - _afterProcess = Stopwatch.GetTimestamp(); - _elapsedTime = (_afterProcess - _beforeProcess) / (double)Stopwatch.Frequency; - } - - protected override bool ShouldRetry(PipelineMessage message, Exception? exception) - => _pipelinePolicy.ShouldRetry(HttpMessage.GetHttpMessage(message), exception); - - protected override async ValueTask ShouldRetryAsync(PipelineMessage message, Exception? exception) - => await _pipelinePolicy.ShouldRetryAsync(HttpMessage.GetHttpMessage(message), exception).ConfigureAwait(false); - - protected override void OnTryComplete(PipelineMessage message) - { - HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); - httpMessage.RetryNumber++; - - AzureCoreEventSource.Singleton.RequestRetrying(httpMessage.Request.ClientRequestId, httpMessage.RetryNumber, _elapsedTime); - - // Reset stopwatch values - _afterProcess = default; - _beforeProcess = default; - _elapsedTime = default; - } - - protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) - { - HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); - - Debug.Assert(tryCount == httpMessage.RetryNumber); - - Response? response = httpMessage.HasResponse ? httpMessage.Response : default; - return _delayStrategy.GetNextDelay(response, tryCount + 1); - } - - protected override async Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) - => await _pipelinePolicy.WaitAsync(time, cancellationToken).ConfigureAwait(false); - - protected override void Wait(TimeSpan time, CancellationToken cancellationToken) - => _pipelinePolicy.Wait(time, cancellationToken); - } -} diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs index 057ddc7957a5..090587100295 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs @@ -2,20 +2,28 @@ // Licensed under the MIT License. using System; +using System.ClientModel; using System.ClientModel.Primitives; +using System.Diagnostics; using System.Threading; using System.Threading.Tasks; +using Azure.Core.Diagnostics; namespace Azure.Core.Pipeline { /// /// Represents a policy that can be overriden to customize whether or not a request will be retried and how long to wait before retrying. /// - public partial class RetryPolicy : HttpPipelinePolicy + public class RetryPolicy : HttpPipelinePolicy { private readonly int _maxRetries; + + /// + /// Gets the delay to use for computing the interval between retry attempts. + /// private readonly DelayStrategy _delayStrategy; - private readonly AzureCoreRetryPolicy _policy; + + private readonly RetryPolicyAdapter _clientModelPolicy; /// /// Initializes a new instance of the class. @@ -27,7 +35,7 @@ public RetryPolicy(int maxRetries = RetryOptions.DefaultMaxRetries, DelayStrateg _maxRetries = maxRetries; _delayStrategy = delayStrategy ?? DelayStrategy.CreateExponentialDelayStrategy(); - _policy = new AzureCoreRetryPolicy(maxRetries, _delayStrategy, this); + _clientModelPolicy = new RetryPolicyAdapter(maxRetries, _delayStrategy, this); } /// @@ -59,28 +67,28 @@ private async ValueTask ProcessSyncOrAsync(HttpMessage message, ReadOnlyMemory + /// This type implements a System.ClientModel + /// and adds the Azure.Core-specific + /// feature of creating an EventSource event with the elapsed time to + /// process the message on each try. + /// + /// It also adapts the Azure.Core that holds + /// it as a member. This is needed so that, if a user has implemented a + /// type derived from Azure.Core and + /// overridden one or more of its virtual methods, when a virtual method + /// is called on the base type from a + /// System.ClientModel context, it will call through to the overridden + /// method on the derived type. + /// + private sealed class RetryPolicyAdapter : ClientRetryPolicy + { + private readonly RetryPolicy _azureCorePolicy; + private readonly DelayStrategy _delayStrategy; + + public RetryPolicyAdapter(int maxRetries, DelayStrategy delay, RetryPolicy policy) + : base(maxRetries) + { + _delayStrategy = delay; + _azureCorePolicy = policy; + } + + protected override void OnSendingRequest(PipelineMessage message) + { + message.SetProperty(typeof(BeforeTimestamp), Stopwatch.GetTimestamp()); + + _azureCorePolicy.OnSendingRequest(HttpMessage.GetHttpMessage(message)); + } + + protected override async ValueTask OnSendingRequestAsync(PipelineMessage message) + { + message.SetProperty(typeof(BeforeTimestamp), Stopwatch.GetTimestamp()); + + await _azureCorePolicy.OnSendingRequestAsync(HttpMessage.GetHttpMessage(message)).ConfigureAwait(false); + } + + protected override void OnRequestSent(PipelineMessage message) + { + _azureCorePolicy.OnRequestSent(HttpMessage.GetHttpMessage(message)); + + if (!message.TryGetProperty(typeof(BeforeTimestamp), out object? beforeTimestamp) || + beforeTimestamp is not long before) + { + throw new InvalidOperationException("'BeforeProcessTimestamp' was not set on message by RetryPolicy."); + } + + long after = Stopwatch.GetTimestamp(); + double elapsed = (after - before) / (double)Stopwatch.Frequency; + + message.SetProperty(typeof(ElapsedTime), elapsed); + } + + protected override async ValueTask OnRequestSentAsync(PipelineMessage message) + { + await _azureCorePolicy.OnRequestSentAsync(HttpMessage.GetHttpMessage(message)).ConfigureAwait(false); + + if (!message.TryGetProperty(typeof(BeforeTimestamp), out object? beforeTimestamp) || + beforeTimestamp is not long before) + { + throw new InvalidOperationException("'BeforeProcessTimestamp' was not set on message by RetryPolicy."); + } + + long after = Stopwatch.GetTimestamp(); + double elapsed = (after - before) / (double)Stopwatch.Frequency; + + message.SetProperty(typeof(ElapsedTime), elapsed); + } + + protected override bool ShouldRetry(PipelineMessage message, Exception? exception) + => _azureCorePolicy.ShouldRetry(HttpMessage.GetHttpMessage(message), exception); + + protected override async ValueTask ShouldRetryAsync(PipelineMessage message, Exception? exception) + => await _azureCorePolicy.ShouldRetryAsync(HttpMessage.GetHttpMessage(message), exception).ConfigureAwait(false); + + protected override void OnTryComplete(PipelineMessage message) + { + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); + httpMessage.RetryNumber++; + + if (!message.TryGetProperty(typeof(ElapsedTime), out object? elapsedTime) || + elapsedTime is not double elapsed) + { + throw new InvalidOperationException("'ElapsedTime' was not set on message by RetryPolicy."); + } + + // This logic can move into System.ClientModel's ClientRetryPolicy + // once we enable EventSource logging there. + AzureCoreEventSource.Singleton.RequestRetrying(httpMessage.Request.ClientRequestId, httpMessage.RetryNumber, elapsed); + + // Reset stopwatch values + message.SetProperty(typeof(BeforeTimestamp), null); + message.SetProperty(typeof(ElapsedTime), null); + } + + protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) + { + HttpMessage httpMessage = HttpMessage.GetHttpMessage(message); + + Debug.Assert(tryCount == httpMessage.RetryNumber); + + Response? response = httpMessage.HasResponse ? httpMessage.Response : default; + return _delayStrategy.GetNextDelay(response, tryCount + 1); + } + + protected override async Task WaitAsync(TimeSpan time, CancellationToken cancellationToken) + => await _azureCorePolicy.WaitAsync(time, cancellationToken).ConfigureAwait(false); + + protected override void Wait(TimeSpan time, CancellationToken cancellationToken) + => _azureCorePolicy.Wait(time, cancellationToken); + + private class BeforeTimestamp { } + + private class ElapsedTime { } + } } } diff --git a/sdk/core/Azure.Core/src/RequestFailedException.cs b/sdk/core/Azure.Core/src/RequestFailedException.cs index 26e2e9c6b8e9..3ab763da0241 100644 --- a/sdk/core/Azure.Core/src/RequestFailedException.cs +++ b/sdk/core/Azure.Core/src/RequestFailedException.cs @@ -146,11 +146,9 @@ public RequestFailedException(int status, string message, string? errorCode, Exc #region ISerializable implementation /// - // TODO protected RequestFailedException(SerializationInfo info, StreamingContext context) - : base("Serialization constructor must be added to ClientResultException.") + : base(info, context) { - Status = info.GetInt32(nameof(Status)); ErrorCode = info.GetString(nameof(ErrorCode)); } @@ -159,7 +157,6 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont { Argument.AssertNotNull(info, nameof(info)); - info.AddValue(nameof(Status), Status); info.AddValue(nameof(ErrorCode), ErrorCode); base.GetObjectData(info, context); diff --git a/sdk/core/Azure.Core/src/RetryOptions.cs b/sdk/core/Azure.Core/src/RetryOptions.cs index d056f884ef06..d3503d0d11e8 100644 --- a/sdk/core/Azure.Core/src/RetryOptions.cs +++ b/sdk/core/Azure.Core/src/RetryOptions.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using System.ComponentModel; namespace Azure.Core { @@ -16,18 +15,10 @@ public class RetryOptions internal static readonly TimeSpan DefaultMaxDelay = TimeSpan.FromMinutes(1); internal static readonly TimeSpan DefaultInitialDelay = TimeSpan.FromSeconds(0.8); - private int _maxRetries = DefaultMaxRetries; - private TimeSpan _delay = DefaultInitialDelay; - private TimeSpan _maxDelay = DefaultMaxDelay; - private RetryMode _retryMode = RetryMode.Exponential; - private TimeSpan _networkTimeout = ClientOptions.DefaultNetworkTimeout; - - private bool _frozen; - /// /// Creates a new instance with default values. /// - internal RetryOptions() + internal RetryOptions() : this(ClientOptions.Default.Retry) { } @@ -50,85 +41,29 @@ internal RetryOptions(RetryOptions? retryOptions) /// /// The maximum number of retry attempts before giving up. /// - public int MaxRetries - { - get => _maxRetries; - set - { - AssertNotFrozen(); - - _maxRetries = value; - } - } + public int MaxRetries { get; set; } = DefaultMaxRetries; /// /// The delay between retry attempts for a fixed approach or the delay /// on which to base calculations for a backoff-based approach. /// If the service provides a Retry-After response header, the next retry will be delayed by the duration specified by the header value. /// - public TimeSpan Delay - { - get => _delay; - set - { - AssertNotFrozen(); - - _delay = value; - } - } + public TimeSpan Delay { get; set; } = DefaultInitialDelay; /// /// The maximum permissible delay between retry attempts when the service does not provide a Retry-After response header. /// If the service provides a Retry-After response header, the next retry will be delayed by the duration specified by the header value. /// - public TimeSpan MaxDelay - { - get => _maxDelay; - set - { - AssertNotFrozen(); - - _maxDelay = value; - } - } + public TimeSpan MaxDelay { get; set; } = DefaultMaxDelay; /// /// The approach to use for calculating retry delays. /// - public RetryMode Mode - { - get => _retryMode; - set - { - AssertNotFrozen(); - - _retryMode = value; - } - } + public RetryMode Mode { get; set; } = RetryMode.Exponential; /// /// The timeout applied to an individual network operations. /// - [EditorBrowsable(EditorBrowsableState.Never)] - public TimeSpan NetworkTimeout - { - get => _networkTimeout; - set - { - AssertNotFrozen(); - - _networkTimeout = value; - } - } - - internal void Freeze() => _frozen = true; - - private void AssertNotFrozen() - { - if (_frozen) - { - throw new InvalidOperationException("Cannot change a ClientOptions instance after it has been used to create a client."); - } - } + public TimeSpan NetworkTimeout { get; set; } = ClientOptions.DefaultNetworkTimeout; } } diff --git a/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs b/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs index 43019e0c5274..48ff30a9b5ae 100644 --- a/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs +++ b/sdk/core/Azure.Core/src/Shared/CancellationHelper.cs @@ -74,4 +74,4 @@ internal static void ThrowIfCancellationRequestedOrTimeout(CancellationToken can } } } -} +} \ No newline at end of file diff --git a/sdk/core/Azure.Core/src/StatusCodeClassifier.cs b/sdk/core/Azure.Core/src/StatusCodeClassifier.cs index ed8715f044a8..dd1b20e042d7 100644 --- a/sdk/core/Azure.Core/src/StatusCodeClassifier.cs +++ b/sdk/core/Azure.Core/src/StatusCodeClassifier.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. using System; -using System.ClientModel.Internal; +using Azure.Core.Internal; namespace Azure.Core { diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs index 5b25ab68714a..17364b055d92 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs @@ -25,12 +25,14 @@ protected ClientResult(System.ClientModel.Primitives.PipelineResponse response) public static System.ClientModel.ClientResult FromValue(T value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public System.ClientModel.Primitives.PipelineResponse GetRawResponse() { throw null; } } - public partial class ClientResultException : System.Exception + public partial class ClientResultException : System.Exception, System.Runtime.Serialization.ISerializable { public ClientResultException(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { } + protected ClientResultException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public ClientResultException(string message, System.ClientModel.Primitives.PipelineResponse? response = null, System.Exception? innerException = null) { } public int Status { get { throw null; } protected set { } } public static System.Threading.Tasks.Task CreateAsync(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { throw null; } + public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public System.ClientModel.Primitives.PipelineResponse? GetRawResponse() { throw null; } } public partial class ClientResult : System.ClientModel.ClientResult @@ -151,7 +153,7 @@ public void Apply(System.ClientModel.Primitives.RequestOptions options) { } public void Dispose() { } protected virtual void Dispose(bool disposing) { } public System.ClientModel.Primitives.PipelineResponse? ExtractResponse() { throw null; } - public void SetProperty(System.Type key, object value) { } + public void SetProperty(System.Type key, object? value) { } public bool TryGetProperty(System.Type key, out object? value) { throw null; } } public abstract partial class PipelineMessageClassifier diff --git a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs index 77fe988d4326..dc4001948314 100644 --- a/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs +++ b/sdk/core/System.ClientModel/api/System.ClientModel.netstandard2.0.cs @@ -25,12 +25,14 @@ protected ClientResult(System.ClientModel.Primitives.PipelineResponse response) public static System.ClientModel.ClientResult FromValue(T value, System.ClientModel.Primitives.PipelineResponse response) { throw null; } public System.ClientModel.Primitives.PipelineResponse GetRawResponse() { throw null; } } - public partial class ClientResultException : System.Exception + public partial class ClientResultException : System.Exception, System.Runtime.Serialization.ISerializable { public ClientResultException(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { } + protected ClientResultException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public ClientResultException(string message, System.ClientModel.Primitives.PipelineResponse? response = null, System.Exception? innerException = null) { } public int Status { get { throw null; } protected set { } } public static System.Threading.Tasks.Task CreateAsync(System.ClientModel.Primitives.PipelineResponse response, System.Exception? innerException = null) { throw null; } + public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public System.ClientModel.Primitives.PipelineResponse? GetRawResponse() { throw null; } } public partial class ClientResult : System.ClientModel.ClientResult @@ -150,7 +152,7 @@ public void Apply(System.ClientModel.Primitives.RequestOptions options) { } public void Dispose() { } protected virtual void Dispose(bool disposing) { } public System.ClientModel.Primitives.PipelineResponse? ExtractResponse() { throw null; } - public void SetProperty(System.Type key, object value) { } + public void SetProperty(System.Type key, object? value) { } public bool TryGetProperty(System.Type key, out object? value) { throw null; } } public abstract partial class PipelineMessageClassifier diff --git a/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs b/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs index 15356c161c7d..f64c10d1b5b7 100644 --- a/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs +++ b/sdk/core/System.ClientModel/src/Convenience/ClientResultException.cs @@ -4,6 +4,7 @@ using System.ClientModel.Internal; using System.ClientModel.Primitives; using System.Globalization; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; @@ -12,7 +13,8 @@ namespace System.ClientModel; /// /// The exception that is thrown when the processing of a client request failed. /// -public class ClientResultException : Exception +[Serializable] +public class ClientResultException : Exception, ISerializable { private const string DefaultMessage = "Service request failed."; @@ -82,6 +84,23 @@ public ClientResultException(string message, PipelineResponse? response = defaul _status = response?.Status ?? 0; } + /// + protected ClientResultException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + _status = info.GetInt32(nameof(Status)); + } + + /// + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + Argument.AssertNotNull(info, nameof(info)); + + info.AddValue(nameof(Status), Status); + + base.GetObjectData(info, context); + } + /// /// Gets the , if any, that led to the exception. /// diff --git a/sdk/core/System.ClientModel/src/Internal/ArrayBackedPropertyBag.cs b/sdk/core/System.ClientModel/src/Internal/ArrayBackedPropertyBag.cs index 78696bd63b79..fcab5b9a5412 100644 --- a/sdk/core/System.ClientModel/src/Internal/ArrayBackedPropertyBag.cs +++ b/sdk/core/System.ClientModel/src/Internal/ArrayBackedPropertyBag.cs @@ -15,9 +15,9 @@ namespace System.ClientModel.Internal; /// internal struct ArrayBackedPropertyBag where TKey : struct, IEquatable { - private (TKey Key, TValue Value) _first; - private (TKey Key, TValue Value) _second; - private (TKey Key, TValue Value)[]? _rest; + private (TKey Key, TValue? Value) _first; + private (TKey Key, TValue? Value) _second; + private (TKey Key, TValue? Value)[]? _rest; private int _count; private readonly object _lock = new(); #if DEBUG @@ -46,7 +46,7 @@ public bool IsEmpty } } - public void GetAt(int index, out TKey key, out TValue value) + public void GetAt(int index, out TKey key, out TValue? value) { CheckDisposed(); (key, value) = index switch @@ -57,7 +57,7 @@ public void GetAt(int index, out TKey key, out TValue value) }; } - public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) + public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue? value) { CheckDisposed(); var index = GetIndex(key); @@ -86,7 +86,7 @@ public bool TryAdd(TKey key, TValue value, out TValue? existingValue) return true; } - public void Set(TKey key, TValue value) + public void Set(TKey key, TValue? value) { CheckDisposed(); var index = GetIndex(key); @@ -131,7 +131,7 @@ public bool TryRemove(TKey key) return false; default: - (TKey Key, TValue Value)[] rest = GetRest(); + (TKey Key, TValue? Value)[] rest = GetRest(); if (IsFirst(key)) { _first = _second; @@ -173,7 +173,7 @@ public bool TryRemove(TKey key) private bool IsSecond(TKey key) => _second.Key.Equals(key); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void AddInternal(TKey key, TValue value) + private void AddInternal(TKey key, TValue? value) { switch (_count) { @@ -196,18 +196,18 @@ private void AddInternal(TKey key, TValue value) default: if (_rest == null) { - _rest = ArrayPool<(TKey Key, TValue Value)>.Shared.Rent(8); + _rest = ArrayPool<(TKey Key, TValue? Value)>.Shared.Rent(8); _rest[_count++ - 2] = (key, value); return; } if (_rest.Length <= _count) { - var larger = ArrayPool<(TKey Key, TValue Value)>.Shared.Rent(_rest.Length << 1); + var larger = ArrayPool<(TKey Key, TValue? Value)>.Shared.Rent(_rest.Length << 1); _rest.CopyTo(larger, 0); var old = _rest; _rest = larger; - ArrayPool<(TKey Key, TValue Value)>.Shared.Return(old, true); + ArrayPool<(TKey Key, TValue? Value)>.Shared.Return(old, true); } _rest[_count++ - 2] = (key, value); return; @@ -215,7 +215,7 @@ private void AddInternal(TKey key, TValue value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SetAt(int index, (TKey Key, TValue Value) value) + private void SetAt(int index, (TKey Key, TValue? Value) value) { if (index == 0) _first = value; @@ -226,7 +226,7 @@ private void SetAt(int index, (TKey Key, TValue Value) value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private TValue GetAt(int index) => index switch + private TValue? GetAt(int index) => index switch { 0 => _first.Value, 1 => _second.Value, @@ -246,7 +246,7 @@ private int GetIndex(TKey key) if (_count <= 2) return -1; - (TKey Key, TValue Value)[] rest = GetRest(); + (TKey Key, TValue? Value)[] rest = GetRest(); int max = _count - 2; for (var i = 0; i < max; i++) { @@ -276,13 +276,13 @@ public void Dispose() return; } - var rest = _rest; + (TKey Key, TValue? Value)[] rest = _rest; _rest = default; - ArrayPool<(TKey Key, TValue Value)>.Shared.Return(rest, true); + ArrayPool<(TKey Key, TValue? Value)>.Shared.Return(rest, true); } } - private (TKey Key, TValue Value)[] GetRest() => _rest ?? + private (TKey Key, TValue? Value)[] GetRest() => _rest ?? throw new InvalidOperationException($"{nameof(_rest)} field is null while {nameof(_count)} == {_count}"); [Conditional("DEBUG")] diff --git a/sdk/core/System.ClientModel/src/Message/ArrayBackedRequestHeaders.cs b/sdk/core/System.ClientModel/src/Message/ArrayBackedRequestHeaders.cs index 860ddacd491c..ff2a540d3361 100644 --- a/sdk/core/System.ClientModel/src/Message/ArrayBackedRequestHeaders.cs +++ b/sdk/core/System.ClientModel/src/Message/ArrayBackedRequestHeaders.cs @@ -39,7 +39,7 @@ public override bool TryGetValue(string name, out string? value) { if (_headers.TryGetValue(new IgnoreCaseString(name), out object? headerValue)) { - value = GetHeaderValueString(name, headerValue); + value = GetHeaderValueString(name, headerValue!); return true; } @@ -51,7 +51,7 @@ public override bool TryGetValues(string name, out IEnumerable? values) { if (_headers.TryGetValue(new IgnoreCaseString(name), out object? value)) { - values = GetHeaderValueEnumerable(name, value); + values = GetHeaderValueEnumerable(name, value!); return true; } @@ -63,16 +63,17 @@ public override IEnumerator> GetEnumerator() => GetHeadersStringValues().GetEnumerator(); // Internal API provided to take advantage of performance-optimized implementation. - internal bool GetNextValue(int index, out string name, out object value) + internal bool GetNextValue(int index, out string name, out object? value) { if (index >= _headers.Count) { name = default!; - value = default!; + value = default; return false; } - _headers.GetAt(index, out IgnoreCaseString headerName, out object headerValue); + _headers.GetAt(index, out IgnoreCaseString headerName, out object? headerValue); + name = headerName; value = headerValue; return true; @@ -83,8 +84,8 @@ private IEnumerable> GetHeadersStringValues() { for (int i = 0; i < _headers.Count; i++) { - _headers.GetAt(i, out IgnoreCaseString name, out object value); - string values = GetHeaderValueString(name, value); + _headers.GetAt(i, out IgnoreCaseString name, out object? value); + string values = GetHeaderValueString(name, value!); yield return new KeyValuePair(name, values); } } diff --git a/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs b/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs index b418189f6efd..7c62f7fc7f66 100644 --- a/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs +++ b/sdk/core/System.ClientModel/src/Message/PipelineMessage.cs @@ -146,7 +146,7 @@ public bool TryGetProperty(Type key, out object? value) => /// The key for the property in the message's property /// bag. /// The value of the property. - public void SetProperty(Type key, object value) => + public void SetProperty(Type key, object? value) => _propertyBag.Set((ulong)key.TypeHandle.Value, value); #endregion diff --git a/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Request.cs b/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Request.cs index e0b5a8ea8997..7239c987e30e 100644 --- a/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Request.cs +++ b/sdk/core/System.ClientModel/src/Pipeline/HttpClientPipelineTransport.Request.cs @@ -103,7 +103,7 @@ internal static HttpRequestMessage BuildHttpRequestMessage(PipelineRequest reque } int i = 0; - while (headers.GetNextValue(i++, out string headerName, out object headerValue)) + while (headers.GetNextValue(i++, out string headerName, out object? headerValue)) { switch (headerValue) { From 0d6820e33b8da2b7b078abde094373a9b910fa2a Mon Sep 17 00:00:00 2001 From: Anne Thompson Date: Mon, 4 Mar 2024 16:07:01 -0800 Subject: [PATCH 47/47] updates from #42329 --- sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs index 090587100295..53e98789b7a5 100644 --- a/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs +++ b/sdk/core/Azure.Core/src/Pipeline/RetryPolicy.cs @@ -209,7 +209,8 @@ protected override void OnRequestSent(PipelineMessage message) if (!message.TryGetProperty(typeof(BeforeTimestamp), out object? beforeTimestamp) || beforeTimestamp is not long before) { - throw new InvalidOperationException("'BeforeProcessTimestamp' was not set on message by RetryPolicy."); + Debug.Fail("'BeforeTimestamp' was not set on message by RetryPolicy."); + return; } long after = Stopwatch.GetTimestamp(); @@ -225,7 +226,8 @@ protected override async ValueTask OnRequestSentAsync(PipelineMessage message) if (!message.TryGetProperty(typeof(BeforeTimestamp), out object? beforeTimestamp) || beforeTimestamp is not long before) { - throw new InvalidOperationException("'BeforeProcessTimestamp' was not set on message by RetryPolicy."); + Debug.Fail("'BeforeTimestamp' was not set on message by RetryPolicy."); + return; } long after = Stopwatch.GetTimestamp(); @@ -248,7 +250,8 @@ protected override void OnTryComplete(PipelineMessage message) if (!message.TryGetProperty(typeof(ElapsedTime), out object? elapsedTime) || elapsedTime is not double elapsed) { - throw new InvalidOperationException("'ElapsedTime' was not set on message by RetryPolicy."); + Debug.Fail("'ElapsedTime' was not set on message by RetryPolicy."); + return; } // This logic can move into System.ClientModel's ClientRetryPolicy