Skip to content

Commit

Permalink
ClientModel: PipelineRequest and PipelineResponse API updates (#42010)
Browse files Browse the repository at this point in the history
* change Core methods to Core properties

* rename ReadContent->BufferContent and export APIs

* nits

* Make PipelineRequest.Uri nullable
  • Loading branch information
annelo-msft authored Feb 16, 2024
1 parent e9f5766 commit 13e6bb4
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 170 deletions.
21 changes: 9 additions & 12 deletions sdk/core/System.ClientModel/api/System.ClientModel.net6.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,14 @@ public abstract partial class PipelineRequest : System.IDisposable
{
protected PipelineRequest() { }
public System.ClientModel.BinaryContent? Content { get { throw null; } set { } }
protected abstract System.ClientModel.BinaryContent? ContentCore { get; set; }
public System.ClientModel.Primitives.PipelineRequestHeaders Headers { get { throw null; } }
protected abstract System.ClientModel.Primitives.PipelineRequestHeaders HeadersCore { get; }
public string Method { get { throw null; } set { } }
public System.Uri Uri { get { throw null; } set { } }
protected abstract string MethodCore { get; set; }
public System.Uri? Uri { get { throw null; } set { } }
protected abstract System.Uri? UriCore { get; set; }
public abstract void Dispose();
protected abstract System.ClientModel.BinaryContent? GetContentCore();
protected abstract System.ClientModel.Primitives.PipelineRequestHeaders GetHeadersCore();
protected abstract string GetMethodCore();
protected abstract System.Uri GetUriCore();
protected abstract void SetContentCore(System.ClientModel.BinaryContent? content);
protected abstract void SetMethodCore(string method);
protected abstract void SetUriCore(System.Uri uri);
}
public abstract partial class PipelineRequestHeaders : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>>, System.Collections.IEnumerable
{
Expand All @@ -209,14 +206,14 @@ protected PipelineResponse() { }
public abstract System.BinaryData Content { get; }
public abstract System.IO.Stream? ContentStream { get; set; }
public System.ClientModel.Primitives.PipelineResponseHeaders Headers { get { throw null; } }
protected abstract System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get; }
public virtual bool IsError { get { throw null; } }
protected internal virtual bool IsErrorCore { get { throw null; } set { } }
public abstract string ReasonPhrase { get; }
public abstract int Status { get; }
public abstract System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.BinaryData> BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract void Dispose();
protected abstract System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore();
public abstract System.BinaryData ReadContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.BinaryData> ReadContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
protected virtual void SetIsErrorCore(bool isError) { }
}
public abstract partial class PipelineResponseHeaders : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>>, System.Collections.IEnumerable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,14 @@ public abstract partial class PipelineRequest : System.IDisposable
{
protected PipelineRequest() { }
public System.ClientModel.BinaryContent? Content { get { throw null; } set { } }
protected abstract System.ClientModel.BinaryContent? ContentCore { get; set; }
public System.ClientModel.Primitives.PipelineRequestHeaders Headers { get { throw null; } }
protected abstract System.ClientModel.Primitives.PipelineRequestHeaders HeadersCore { get; }
public string Method { get { throw null; } set { } }
public System.Uri Uri { get { throw null; } set { } }
protected abstract string MethodCore { get; set; }
public System.Uri? Uri { get { throw null; } set { } }
protected abstract System.Uri? UriCore { get; set; }
public abstract void Dispose();
protected abstract System.ClientModel.BinaryContent? GetContentCore();
protected abstract System.ClientModel.Primitives.PipelineRequestHeaders GetHeadersCore();
protected abstract string GetMethodCore();
protected abstract System.Uri GetUriCore();
protected abstract void SetContentCore(System.ClientModel.BinaryContent? content);
protected abstract void SetMethodCore(string method);
protected abstract void SetUriCore(System.Uri uri);
}
public abstract partial class PipelineRequestHeaders : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>>, System.Collections.IEnumerable
{
Expand All @@ -208,14 +205,14 @@ protected PipelineResponse() { }
public abstract System.BinaryData Content { get; }
public abstract System.IO.Stream? ContentStream { get; set; }
public System.ClientModel.Primitives.PipelineResponseHeaders Headers { get { throw null; } }
protected abstract System.ClientModel.Primitives.PipelineResponseHeaders HeadersCore { get; }
public virtual bool IsError { get { throw null; } }
protected internal virtual bool IsErrorCore { get { throw null; } set { } }
public abstract string ReasonPhrase { get; }
public abstract int Status { get; }
public abstract System.BinaryData BufferContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.BinaryData> BufferContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract void Dispose();
protected abstract System.ClientModel.Primitives.PipelineResponseHeaders GetHeadersCore();
public abstract System.BinaryData ReadContent(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.ValueTask<System.BinaryData> ReadContentAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
protected virtual void SetIsErrorCore(bool isError) { }
}
public abstract partial class PipelineResponseHeaders : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>>, System.Collections.IEnumerable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ private static async ValueTask<string> CreateMessageSyncOrAsync(PipelineResponse
{
if (async)
{
await response.ReadContentAsync().ConfigureAwait(false);
await response.BufferContentAsync().ConfigureAwait(false);
}
else
{
response.ReadContent();
response.BufferContent();
}

StringBuilder messageBuilder = new();
Expand Down
32 changes: 13 additions & 19 deletions sdk/core/System.ClientModel/src/Message/PipelineRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,31 @@ public abstract class PipelineRequest : IDisposable
/// </summary>
public string Method
{
get => GetMethodCore();
set => SetMethodCore(value);
get => MethodCore;
set => MethodCore = value;
}

protected abstract string GetMethodCore();
protected abstract string MethodCore { get; set; }

protected abstract void SetMethodCore(string method);

public Uri Uri
public Uri? Uri
{
get => GetUriCore();
set => SetUriCore(value);
get => UriCore;
set => UriCore = value;
}

protected abstract Uri GetUriCore();

protected abstract void SetUriCore(Uri uri);
protected abstract Uri? UriCore { get; set; }

public PipelineRequestHeaders Headers { get => GetHeadersCore(); }
public PipelineRequestHeaders Headers => HeadersCore;

protected abstract PipelineRequestHeaders GetHeadersCore();
protected abstract PipelineRequestHeaders HeadersCore { get; }

public BinaryContent? Content
{
get => GetContentCore();
set => SetContentCore(value);
get => ContentCore;
set => ContentCore = value;
}

protected abstract BinaryContent? GetContentCore();

protected abstract void SetContentCore(BinaryContent? content);
protected abstract BinaryContent? ContentCore { get; set; }

public abstract void Dispose();
}
}
18 changes: 6 additions & 12 deletions sdk/core/System.ClientModel/src/Message/PipelineResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ public abstract class PipelineResponse : IDisposable
// TODO(matell): The .NET Framework team plans to add BinaryData.Empty in dotnet/runtime#49670, and we can use it then.
internal static readonly BinaryData s_EmptyBinaryData = new(Array.Empty<byte>());

private bool _isError = false;

/// <summary>
/// Gets the HTTP status code.
/// </summary>
Expand All @@ -24,9 +22,9 @@ public abstract class PipelineResponse : IDisposable
/// </summary>
public abstract string ReasonPhrase { get; }

public PipelineResponseHeaders Headers => GetHeadersCore();
public PipelineResponseHeaders Headers => HeadersCore;

protected abstract PipelineResponseHeaders GetHeadersCore();
protected abstract PipelineResponseHeaders HeadersCore { get; }

/// <summary>
/// Gets the contents of HTTP response. Returns <c>null</c> for responses without content.
Expand All @@ -35,22 +33,18 @@ public abstract class PipelineResponse : IDisposable

public abstract BinaryData Content { get; }

public abstract BinaryData ReadContent(CancellationToken cancellationToken = default);
public abstract BinaryData BufferContent(CancellationToken cancellationToken = default);

public abstract ValueTask<BinaryData> ReadContentAsync(CancellationToken cancellationToken = default);
public abstract ValueTask<BinaryData> BufferContentAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Indicates whether the status code of the returned response is considered
/// an error code.
/// </summary>
// IsError must be virtual in order to maintain Azure.Core back-compatibility.
public virtual bool IsError => _isError;

// We have to have a separate method for setting IsError so that the IsError
// setter doesn't become virtual when we make the getter virtual.
internal void SetIsError(bool isError) => SetIsErrorCore(isError);
public virtual bool IsError => IsErrorCore;

protected virtual void SetIsErrorCore(bool isError) => _isError = isError;
protected internal virtual bool IsErrorCore { get; set; }

public abstract void Dispose();
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,41 +32,35 @@ protected internal HttpPipelineRequest()
_headers = new ArrayBackedRequestHeaders();
}

protected override string GetMethodCore()
=> _method;

protected override void SetMethodCore(string method)
protected override string MethodCore
{
Argument.AssertNotNull(method, nameof(method));
get => _method;
set
{
Argument.AssertNotNull(value, nameof(value));

_method = method;
_method = value;
}
}

protected override Uri GetUriCore()
protected override Uri? UriCore
{
if (_uri is null)
get => _uri;
set
{
throw new InvalidOperationException("Uri has not been set on this instance.");
}
Argument.AssertNotNull(value, nameof(value));

return _uri;
_uri = value;
}
}

protected override void SetUriCore(Uri uri)
protected override BinaryContent? ContentCore
{
Argument.AssertNotNull(uri, nameof(uri));

_uri = uri;
get => _content;
set => _content = value;
}

protected override BinaryContent? GetContentCore()
=> _content;

protected override void SetContentCore(BinaryContent? content)
=> _content = content;

protected override PipelineRequestHeaders GetHeadersCore()
=> _headers;
protected override PipelineRequestHeaders HeadersCore => _headers;

// PATCH value needed for compat with pre-net5.0 TFMs
private static readonly HttpMethod _patchMethod = new HttpMethod("PATCH");
Expand All @@ -82,11 +76,16 @@ private static HttpMethod ToHttpMethod(string method)
"DELETE" => HttpMethod.Delete,
"PATCH" => _patchMethod,
_ => new HttpMethod(method),
}; ;
};
}

internal static HttpRequestMessage BuildHttpRequestMessage(PipelineRequest request, CancellationToken cancellationToken)
{
if (request.Uri is null)
{
throw new InvalidOperationException("Uri must be set on message request prior to sending message.");
}

HttpMethod method = ToHttpMethod(request.Method);
Uri uri = request.Uri;
HttpRequestMessage httpRequest = new HttpRequestMessage(method, uri);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public HttpClientTransportResponse(HttpResponseMessage httpResponse)
public override string ReasonPhrase
=> _httpResponse.ReasonPhrase ?? string.Empty;

protected override PipelineResponseHeaders GetHeadersCore()
protected override PipelineResponseHeaders HeadersCore
=> new HttpClientResponseHeaders(_httpResponse, _httpResponseContent);

public override Stream? ContentStream
Expand Down Expand Up @@ -80,17 +80,17 @@ public override BinaryData Content

if (_contentStream is null || _contentStream is MemoryStream)
{
return ReadContent();
return BufferContent();
}

throw new InvalidOperationException($"The response is not buffered.");
}
}

public override BinaryData ReadContent(CancellationToken cancellationToken = default)
public override BinaryData BufferContent(CancellationToken cancellationToken = default)
=> ReadContentSyncOrAsync(cancellationToken, async: false).EnsureCompleted();

public override async ValueTask<BinaryData> ReadContentAsync(CancellationToken cancellationToken = default)
public override async ValueTask<BinaryData> BufferContentAsync(CancellationToken cancellationToken = default)
=> await ReadContentSyncOrAsync(cancellationToken, async: true).ConfigureAwait(false);

private async ValueTask<BinaryData> ReadContentSyncOrAsync(CancellationToken cancellationToken, bool async)
Expand Down Expand Up @@ -160,7 +160,7 @@ protected virtual void Dispose(bool disposing)

if (ContentStream is MemoryStream)
{
ReadContent();
BufferContent();
}

Stream? contentStream = _contentStream;
Expand Down
6 changes: 3 additions & 3 deletions sdk/core/System.ClientModel/src/Pipeline/PipelineTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private async ValueTask ProcessSyncOrAsync(PipelineMessage message, bool async)
}

message.AssertResponse();
message.Response!.SetIsError(ClassifyResponse(message));
message.Response!.IsErrorCore = ClassifyResponse(message);

// The remainder of the method handles response content according to
// buffering logic specified by value of message.BufferResponse.
Expand Down Expand Up @@ -127,11 +127,11 @@ private async ValueTask ProcessSyncOrAsync(PipelineMessage message, bool async)

if (async)
{
await message.Response.ReadContentAsync(timeoutTokenSource.Token).ConfigureAwait(false);
await message.Response.BufferContentAsync(timeoutTokenSource.Token).ConfigureAwait(false);
}
else
{
message.Response.ReadContent(timeoutTokenSource.Token);
message.Response.BufferContent(timeoutTokenSource.Token);
}
}
// We dispose stream on timeout or user cancellation so catch and check if
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,26 @@ public MockPipelineRequest()
_method = "GET";
}

protected override BinaryContent? GetContentCore()
=> _content;
protected override BinaryContent? ContentCore
{
get => _content;
set => _content = value;
}

protected override PipelineRequestHeaders GetHeadersCore()
protected override PipelineRequestHeaders HeadersCore
=> _headers;

protected override string GetMethodCore()
=> _method;

protected override Uri GetUriCore()
protected override string MethodCore
{
if (_uri is null)
{
throw new InvalidOperationException("Uri has not be set on HttpMessageRequest instance.");
}

return _uri;
get => _method;
set => _method = value;
}

protected override void SetContentCore(BinaryContent? content)
=> _content = content;

protected override void SetMethodCore(string method)
=> _method = method;

protected override void SetUriCore(Uri uri)
=> _uri = uri;
protected override Uri? UriCore
{
get => _uri;
set => _uri = value;
}

public sealed override void Dispose()
{
Expand All @@ -71,4 +64,4 @@ protected void Dispose(bool disposing)
_disposed = true;
}
}
}
}
Loading

0 comments on commit 13e6bb4

Please sign in to comment.