mirror of https://github.com/dapr/dotnet-sdk.git
Rename and cleanup of HTTPExtension (#488)
* Rename and cleanup of HTTPExtension Fixes: #421 This change renames `HTTPExtension`->`HttpInvocationOptions`. This is more idiomatic in .NET and reflects existing naming conventions (options or settings for parameters). Also changes to use the `System.Net.Http.HttpMethod` type for the http method, and globally prefer the term `method` over `verb`. Every .NET API that I'm aware of uses 'method', as does rfc7231. * One more rename
This commit is contained in:
parent
47b59b4a97
commit
116d984b4e
|
|
@ -10,7 +10,6 @@ namespace DaprClient
|
|||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Dapr.Client;
|
||||
using Dapr.Client.Http;
|
||||
using Grpc.Core;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -161,7 +160,7 @@ namespace DaprClient
|
|||
// Invokes a POST method named "depoit" that takes input of type "Transaction" as define in the RoutingSample.
|
||||
Console.WriteLine("invoking");
|
||||
|
||||
var a = await client.InvokeMethodAsync<object, Account>("routing", "deposit", data, HTTPExtension.UsingPost());
|
||||
var a = await client.InvokeMethodAsync<object, Account>("routing", "deposit", data, HttpInvocationOptions.UsingPost());
|
||||
Console.WriteLine("Returned: id:{0} | Balance:{1}", a.Id, a.Balance);
|
||||
|
||||
Console.WriteLine("Completed");
|
||||
|
|
@ -182,7 +181,7 @@ namespace DaprClient
|
|||
var data = new { id = "17", amount = (decimal)10, };
|
||||
|
||||
// Invokes a POST method named "Withdraw" that takes input of type "Transaction" as define in the RoutingSample.
|
||||
await client.InvokeMethodAsync<object>("routing", "Withdraw", data, HTTPExtension.UsingPost());
|
||||
await client.InvokeMethodAsync<object>("routing", "Withdraw", data, HttpInvocationOptions.UsingPost());
|
||||
|
||||
Console.WriteLine("Completed");
|
||||
}
|
||||
|
|
@ -201,7 +200,7 @@ namespace DaprClient
|
|||
Console.WriteLine("Invoking balance");
|
||||
|
||||
// Invokes a GET method named "hello" that takes input of type "MyData" and returns a string.
|
||||
var res = await client.InvokeMethodAsync<Account>("routing", "17", HTTPExtension.UsingGet());
|
||||
var res = await client.InvokeMethodAsync<Account>("routing", "17", HttpInvocationOptions.UsingGet());
|
||||
|
||||
Console.WriteLine($"Received balance {res.Balance}");
|
||||
}
|
||||
|
|
@ -214,7 +213,7 @@ namespace DaprClient
|
|||
try
|
||||
{
|
||||
// Invokes a POST method named "throwException" that takes input of type "Transaction" as defined in the ControllerSample.
|
||||
await client.InvokeMethodAsync("controller", "throwException", data, HTTPExtension.UsingPost());
|
||||
await client.InvokeMethodAsync("controller", "throwException", data, HttpInvocationOptions.UsingPost());
|
||||
}
|
||||
catch (RpcException ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -87,13 +87,13 @@ The method *InvokeWithdrawServiceOperationAsync* demonstrates how to use DAPR .N
|
|||
|
||||
var data = new { id = "17", amount = (decimal)10, };
|
||||
|
||||
// The HTTPExtension object is needed to specify additional information such as the HTTP verb and an optional query string, because the receiving service is listening on HTTP. If it were listening on gRPC, it is not needed.
|
||||
HTTPExtension httpExtension = new HTTPExtension()
|
||||
// The HttpInvocationOptions object is needed to specify additional information such as the HTTP method and an optional query string, because the receiving service is listening on HTTP. If it were listening on gRPC, it is not needed.
|
||||
var httpOptions = new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Post
|
||||
Method = HttpMethod.Post
|
||||
};
|
||||
|
||||
await client.InvokeMethodAsync<object>("routing", "Withdraw", data, httpExtension);
|
||||
await client.InvokeMethodAsync<object>("routing", "Withdraw", data, httpOptions);
|
||||
```
|
||||
|
||||
Because, the same operation subscribes events on the *withdraw* topic, it can be invoked by event:
|
||||
|
|
|
|||
|
|
@ -75,13 +75,13 @@ namespace Dapr.Client
|
|||
/// </summary>
|
||||
/// <param name="appId">The Dapr application id to invoke the method on.</param>
|
||||
/// <param name="methodName">The name of the method to invoke.</param>
|
||||
/// <param name="httpExtension">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="httpOptions">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="Task" /> that will complete when the operation has completed.</returns>
|
||||
public abstract Task InvokeMethodAsync(
|
||||
string appId,
|
||||
string methodName,
|
||||
Dapr.Client.Http.HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -91,14 +91,14 @@ namespace Dapr.Client
|
|||
/// <param name="appId">The Dapr application id to invoke the method on.</param>
|
||||
/// <param name="methodName">The name of the method to invoke.</param>
|
||||
/// <param name="data">Data to pass to the method</param>
|
||||
/// <param name="httpExtension">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="httpOptions">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{T}" /> that will return the value when the operation has completed.</returns>
|
||||
public abstract Task InvokeMethodAsync<TRequest>(
|
||||
string appId,
|
||||
string methodName,
|
||||
TRequest data,
|
||||
Dapr.Client.Http.HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -107,13 +107,13 @@ namespace Dapr.Client
|
|||
/// <typeparam name="TResponse">The type of the object in the response.</typeparam>
|
||||
/// <param name="appId">The Dapr application id to invoke the method on.</param>
|
||||
/// <param name="methodName">The name of the method to invoke.</param>
|
||||
/// <param name="httpExtension">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="httpOptions">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{T}" /> that will return the value when the operation has completed.</returns>
|
||||
public abstract ValueTask<TResponse> InvokeMethodAsync<TResponse>(
|
||||
string appId,
|
||||
string methodName,
|
||||
Dapr.Client.Http.HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -124,14 +124,14 @@ namespace Dapr.Client
|
|||
/// <param name="appId">The Dapr application id to invoke the method on.</param>
|
||||
/// <param name="methodName">The name of the method to invoke.</param>
|
||||
/// <param name="data">Data to pass to the method</param>
|
||||
/// <param name="httpExtension">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="httpOptions">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{T}" /> that will return the value when the operation has completed.</returns>
|
||||
public abstract ValueTask<TResponse> InvokeMethodAsync<TRequest, TResponse>(
|
||||
string appId,
|
||||
string methodName,
|
||||
TRequest data,
|
||||
Dapr.Client.Http.HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -140,14 +140,14 @@ namespace Dapr.Client
|
|||
/// <param name="appId">The Dapr application id to invoke the method on.</param>
|
||||
/// <param name="methodName">The name of the method to invoke.</param>
|
||||
/// <param name="data">Data to pass to the method</param>
|
||||
/// <param name="httpExtension">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="httpOptions">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="Task{InvokeResponse}" /> that will return the value when the operation has completed.</returns>
|
||||
public abstract Task<InvocationResponse<TResponse>> InvokeMethodWithResponseAsync<TRequest, TResponse>(
|
||||
string appId,
|
||||
string methodName,
|
||||
TRequest data,
|
||||
Dapr.Client.Http.HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -156,14 +156,14 @@ namespace Dapr.Client
|
|||
/// <param name="appId">The Dapr application id to invoke the method on.</param>
|
||||
/// <param name="methodName">The name of the method to invoke.</param>
|
||||
/// <param name="data">Byte array to pass to the method</param>
|
||||
/// <param name="httpExtension">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="httpOptions">Additional fields that may be needed if the receiving app is listening on HTTP.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{T}" /> that will return the value when the operation has completed.</returns>
|
||||
public abstract Task<InvocationResponse<byte[]>> InvokeMethodRawAsync(
|
||||
string appId,
|
||||
string methodName,
|
||||
byte[] data,
|
||||
Dapr.Client.Http.HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -9,22 +9,34 @@ namespace Dapr.Client
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Dapr.Client.Http;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Autogenerated = Autogen.Grpc.v1;
|
||||
using Autogenerated = Dapr.Client.Autogen.Grpc.v1;
|
||||
using GrpcVerb = Dapr.Client.Autogen.Grpc.v1.HTTPExtension.Types.Verb;
|
||||
|
||||
/// <summary>
|
||||
/// A client for interacting with the Dapr endpoints.
|
||||
/// </summary>
|
||||
internal class DaprClientGrpc : DaprClient
|
||||
{
|
||||
private static readonly Dictionary<HttpMethod, GrpcVerb> methodToVerb = new Dictionary<HttpMethod, GrpcVerb>()
|
||||
{
|
||||
{ new HttpMethod("CONNECT"), GrpcVerb.Connect },
|
||||
{ HttpMethod.Delete, GrpcVerb.Delete },
|
||||
{ HttpMethod.Get, GrpcVerb.Get },
|
||||
{ HttpMethod.Head, GrpcVerb.Head },
|
||||
{ HttpMethod.Options, GrpcVerb.Options },
|
||||
{ HttpMethod.Post, GrpcVerb.Post },
|
||||
{ HttpMethod.Put, GrpcVerb.Put },
|
||||
{ HttpMethod.Trace, GrpcVerb.Trace },
|
||||
};
|
||||
|
||||
private static readonly string DaprErrorInfoHttpCodeMetadata = "http.code";
|
||||
private static readonly string DaprErrorInfoHttpErrorMetadata = "http.error_message";
|
||||
private static readonly string GrpcStatusDetails = "grpc-status-details-bin";
|
||||
|
|
@ -154,13 +166,13 @@ namespace Dapr.Client
|
|||
public override async Task InvokeMethodAsync(
|
||||
string appId,
|
||||
string methodName,
|
||||
HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentVerifier.ThrowIfNullOrEmpty(appId, nameof(appId));
|
||||
ArgumentVerifier.ThrowIfNullOrEmpty(methodName, nameof(methodName));
|
||||
|
||||
var (request, callOptions) = this.MakeInvokeRequestAsync(appId, methodName, null, httpExtension, cancellationToken);
|
||||
var (request, callOptions) = this.MakeInvokeRequestAsync(appId, methodName, null, httpOptions, cancellationToken);
|
||||
await client.InvokeServiceAsync(request, callOptions);
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +180,7 @@ namespace Dapr.Client
|
|||
string appId,
|
||||
string methodName,
|
||||
TRequest data,
|
||||
HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentVerifier.ThrowIfNullOrEmpty(appId, nameof(appId));
|
||||
|
|
@ -182,14 +194,14 @@ namespace Dapr.Client
|
|||
|
||||
Autogenerated.InvokeServiceRequest request;
|
||||
CallOptions callOptions;
|
||||
(request, callOptions) = this.MakeInvokeRequestAsync(appId, methodName, serializedData, httpExtension, cancellationToken);
|
||||
(request, callOptions) = this.MakeInvokeRequestAsync(appId, methodName, serializedData, httpOptions, cancellationToken);
|
||||
await client.InvokeServiceAsync(request, callOptions);
|
||||
}
|
||||
|
||||
public override async ValueTask<TResponse> InvokeMethodAsync<TResponse>(
|
||||
string appId,
|
||||
string methodName,
|
||||
HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentVerifier.ThrowIfNullOrEmpty(appId, nameof(appId));
|
||||
|
|
@ -197,7 +209,7 @@ namespace Dapr.Client
|
|||
|
||||
Autogenerated.InvokeServiceRequest request;
|
||||
CallOptions callOptions;
|
||||
(request, callOptions) = this.MakeInvokeRequestAsync(appId, methodName, null, httpExtension, cancellationToken);
|
||||
(request, callOptions) = this.MakeInvokeRequestAsync(appId, methodName, null, httpOptions, cancellationToken);
|
||||
var response = await client.InvokeServiceAsync(request, callOptions);
|
||||
return response.Data.Value.IsEmpty ? default : TypeConverters.FromAny<TResponse>(response.Data, this.jsonSerializerOptions);
|
||||
}
|
||||
|
|
@ -206,7 +218,7 @@ namespace Dapr.Client
|
|||
string appId,
|
||||
string methodName,
|
||||
TRequest data,
|
||||
HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentVerifier.ThrowIfNullOrEmpty(appId, nameof(appId));
|
||||
|
|
@ -217,7 +229,7 @@ namespace Dapr.Client
|
|||
AppId = appId,
|
||||
MethodName = methodName,
|
||||
Body = data,
|
||||
HttpExtension = httpExtension,
|
||||
HttpOptions = httpOptions,
|
||||
};
|
||||
|
||||
var invokeResponse = await this.MakeInvokeRequestAsyncWithResponse<TRequest, TResponse>(request, false, cancellationToken);
|
||||
|
|
@ -228,7 +240,7 @@ namespace Dapr.Client
|
|||
string appId,
|
||||
string methodName,
|
||||
TRequest data,
|
||||
Dapr.Client.Http.HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentVerifier.ThrowIfNull(appId, nameof(appId));
|
||||
|
|
@ -239,7 +251,7 @@ namespace Dapr.Client
|
|||
AppId = appId,
|
||||
MethodName = methodName,
|
||||
Body = data,
|
||||
HttpExtension = httpExtension,
|
||||
HttpOptions = httpOptions,
|
||||
};
|
||||
|
||||
var invokeResponse = await this.MakeInvokeRequestAsyncWithResponse<TRequest, TResponse>(request, false, cancellationToken);
|
||||
|
|
@ -251,7 +263,7 @@ namespace Dapr.Client
|
|||
string appId,
|
||||
string methodName,
|
||||
byte[] data,
|
||||
HTTPExtension httpExtension = default,
|
||||
HttpInvocationOptions httpOptions = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentVerifier.ThrowIfNullOrEmpty(appId, nameof(appId));
|
||||
|
|
@ -262,7 +274,7 @@ namespace Dapr.Client
|
|||
AppId = appId,
|
||||
MethodName = methodName,
|
||||
Body = data,
|
||||
HttpExtension = httpExtension,
|
||||
HttpOptions = httpOptions,
|
||||
};
|
||||
|
||||
var invokeResponse = await this.MakeInvokeRequestAsyncWithResponse<byte[], byte[]>(request, true, cancellationToken);
|
||||
|
|
@ -301,35 +313,35 @@ namespace Dapr.Client
|
|||
string appId,
|
||||
string methodName,
|
||||
Any data,
|
||||
HTTPExtension httpExtension,
|
||||
HttpInvocationOptions httpOptions,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var protoHTTPExtension = new Autogenerated.HTTPExtension();
|
||||
var contentType = "";
|
||||
Metadata headers = null;
|
||||
|
||||
if (httpExtension != null)
|
||||
if (httpOptions != null)
|
||||
{
|
||||
protoHTTPExtension.Verb = ConvertHTTPVerb(httpExtension.Verb);
|
||||
protoHTTPExtension.Verb = ConvertHTTPVerb(httpOptions.Method);
|
||||
|
||||
if (httpExtension.QueryString != null)
|
||||
if (httpOptions.QueryString != null)
|
||||
{
|
||||
foreach (var (key, value) in httpExtension.QueryString)
|
||||
foreach (var (key, value) in httpOptions.QueryString)
|
||||
{
|
||||
protoHTTPExtension.Querystring.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (httpExtension.Headers != null)
|
||||
if (httpOptions.Headers != null)
|
||||
{
|
||||
headers = new Metadata();
|
||||
foreach (var (key, value) in httpExtension.Headers)
|
||||
foreach (var (key, value) in httpOptions.Headers)
|
||||
{
|
||||
headers.Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
contentType = httpExtension.ContentType ?? Constants.ContentTypeApplicationJson;
|
||||
contentType = httpOptions.ContentType ?? Constants.ContentTypeApplicationJson;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -389,7 +401,7 @@ namespace Dapr.Client
|
|||
var invokeResponse = new InvocationResponse<TResponse>();
|
||||
Autogenerated.InvokeServiceRequest invokeRequest;
|
||||
CallOptions callOptions;
|
||||
(invokeRequest, callOptions) = this.MakeInvokeRequestAsync(request.AppId, request.MethodName, serializedData, request.HttpExtension, cancellationToken);
|
||||
(invokeRequest, callOptions) = this.MakeInvokeRequestAsync(request.AppId, request.MethodName, serializedData, request.HttpOptions, cancellationToken);
|
||||
var grpcCall = client.InvokeServiceAsync(invokeRequest, callOptions);
|
||||
|
||||
var response = await grpcCall.ResponseAsync;
|
||||
|
|
@ -886,20 +898,14 @@ namespace Dapr.Client
|
|||
return stateRequestOptions;
|
||||
}
|
||||
|
||||
private static Autogenerated.HTTPExtension.Types.Verb ConvertHTTPVerb(HTTPVerb verb)
|
||||
private static GrpcVerb ConvertHTTPVerb(HttpMethod method)
|
||||
{
|
||||
return verb switch
|
||||
if (methodToVerb.TryGetValue(method, out var converted))
|
||||
{
|
||||
HTTPVerb.Get => Autogenerated.HTTPExtension.Types.Verb.Get,
|
||||
HTTPVerb.Head => Autogenerated.HTTPExtension.Types.Verb.Head,
|
||||
HTTPVerb.Post => Autogenerated.HTTPExtension.Types.Verb.Post,
|
||||
HTTPVerb.Put => Autogenerated.HTTPExtension.Types.Verb.Put,
|
||||
HTTPVerb.Delete => Autogenerated.HTTPExtension.Types.Verb.Delete,
|
||||
HTTPVerb.Connect => Autogenerated.HTTPExtension.Types.Verb.Connect,
|
||||
HTTPVerb.Options => Autogenerated.HTTPExtension.Types.Verb.Options,
|
||||
HTTPVerb.Trace => Autogenerated.HTTPExtension.Types.Verb.Trace,
|
||||
_ => throw new NotImplementedException($"Service invocation with verb '{verb}' is not supported")
|
||||
};
|
||||
return converted;
|
||||
}
|
||||
|
||||
throw new NotImplementedException($"Service invocation with HTTP method '{method}' is not supported");
|
||||
}
|
||||
|
||||
private static Autogenerated.StateOptions.Types.StateConsistency GetStateConsistencyForConsistencyMode(ConsistencyMode consistencyMode)
|
||||
|
|
|
|||
|
|
@ -4,10 +4,6 @@
|
|||
// ------------------------------------------------------------
|
||||
namespace Dapr.Client
|
||||
{
|
||||
using Dapr.Client.Http;
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
/// <summary>
|
||||
/// This class is only needed if the app you are calling app is listening on gRPC.
|
||||
/// It contains propertes that represent status info that may be populated for an gRPC response.
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
namespace Dapr.Client.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// The HTTP verb to use for this message.
|
||||
/// </summary>
|
||||
public enum HTTPVerb
|
||||
{
|
||||
/// <summary>
|
||||
/// The HTTP verb GET
|
||||
/// </summary>
|
||||
Get,
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP verb HEAD
|
||||
/// </summary>
|
||||
Head,
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP verb POST
|
||||
/// </summary>
|
||||
Post,
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP verb PUT
|
||||
/// </summary>
|
||||
Put,
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP verb DELETE
|
||||
/// </summary>
|
||||
Delete,
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP verb CONNECT
|
||||
/// </summary>
|
||||
Connect,
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP verb OPTIONS
|
||||
/// </summary>
|
||||
Options,
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP verb TRACE
|
||||
/// </summary>
|
||||
Trace
|
||||
}
|
||||
}
|
||||
|
|
@ -3,22 +3,23 @@
|
|||
// Licensed under the MIT License.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
namespace Dapr.Client.Http
|
||||
namespace Dapr.Client
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
|
||||
/// <summary>
|
||||
/// This class is only needed if the app you are calling is listening on HTTP.
|
||||
/// It contains propertes that represent data may be populated for an HTTP receiver.
|
||||
/// Represents options for invoking a reciever over HTTP. Allows specifying HTTP-specific semantics of the
|
||||
/// request like the HTTP method, query string, and headers.
|
||||
/// </summary>
|
||||
public class HTTPExtension
|
||||
public class HttpInvocationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The constructor.
|
||||
/// Initializes a new instance of <see cref="HttpInvocationOptions" />.
|
||||
/// </summary>
|
||||
public HTTPExtension()
|
||||
public HttpInvocationOptions()
|
||||
{
|
||||
this.Verb = HTTPVerb.Post;
|
||||
this.Method = HttpMethod.Post;
|
||||
this.QueryString = new Dictionary<string, string>();
|
||||
this.Headers = new Dictionary<string, string>();
|
||||
}
|
||||
|
|
@ -29,9 +30,9 @@ namespace Dapr.Client.Http
|
|||
public string ContentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is the HTTP verb.
|
||||
/// This is the HTTP method.
|
||||
/// </summary>
|
||||
public HTTPVerb Verb { get; set; }
|
||||
public HttpMethod Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This represents a collection of query strings.
|
||||
|
|
@ -46,83 +47,84 @@ namespace Dapr.Client.Http
|
|||
#region Fluent Methods
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Get"/> request
|
||||
/// This convenience method allow constructing a <see cref="HttpMethod.Get"/> request.
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingGet() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingGet() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Get
|
||||
Method = HttpMethod.Get
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Post"/> request
|
||||
/// This convenience method allow constructing a <see cref="HttpMethod.Post"/> request.
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingPost() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingPost() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Post
|
||||
Method = HttpMethod.Post
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Put"/> request
|
||||
/// This convenience method allow constructing a <see cref="HttpMethod.Put"/> request.
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingPut() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingPut() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Put
|
||||
Method = HttpMethod.Put
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Delete"/> request
|
||||
/// This convenience method allow constructing a <see cref="HttpMethod.Delete"/> request.
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingDelete() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingDelete() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Delete
|
||||
Method = HttpMethod.Delete
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Connect"/> request
|
||||
/// This convenience method allow constructing an HTTP <c>CONNECT</c> request.
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingConnect() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingConnect() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Connect
|
||||
// CONNECT is extremely specialized and uncommon - .NET doesn't define a constant for it.
|
||||
Method = new HttpMethod("CONNECT")
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Options"/> request
|
||||
/// This convenience method allow constructing a <see cref="HttpMethod.Options"/> request.
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingOptions() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingOptions() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Options
|
||||
Method = HttpMethod.Options
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Head"/> request
|
||||
/// This convenience method allow constructing a <see cref="HttpMethod.Head"/> request
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingHead() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingHead() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Head
|
||||
Method = HttpMethod.Head
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a <see cref="HTTPVerb.Trace"/> request
|
||||
/// This convenience method allow constructing a <see cref="HttpMethod.Trace"/> request
|
||||
/// </summary>
|
||||
/// <returns>Instance of <see cref="HTTPExtension"/></returns>
|
||||
public static HTTPExtension UsingTrace() => new HTTPExtension()
|
||||
/// <returns>Instance of <see cref="HttpInvocationOptions"/></returns>
|
||||
public static HttpInvocationOptions UsingTrace() => new HttpInvocationOptions()
|
||||
{
|
||||
Verb = HTTPVerb.Trace
|
||||
Method = HttpMethod.Trace
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// This convenience method allow constructing a request with Query Params
|
||||
/// </summary>
|
||||
/// <param name="param">The query parameter you want to add</param>
|
||||
/// <returns>An updated instance of the same <see cref="HTTPExtension"/></returns>
|
||||
public HTTPExtension WithQueryParam(KeyValuePair<string, string> param)
|
||||
/// <returns>An updated instance of the same <see cref="HttpInvocationOptions"/></returns>
|
||||
public HttpInvocationOptions WithQueryParam(KeyValuePair<string, string> param)
|
||||
{
|
||||
this.QueryString.Add(param.Key, param.Value);
|
||||
return this;
|
||||
|
|
@ -133,8 +135,8 @@ namespace Dapr.Client.Http
|
|||
/// </summary>
|
||||
/// <param name="name">Name of the query parameter</param>
|
||||
/// <param name="value">Value of the query parameter</param>
|
||||
/// <returns>An updated instance of the same <see cref="HTTPExtension"/></returns>
|
||||
public HTTPExtension WithQueryParam(string name, string value)
|
||||
/// <returns>An updated instance of the same <see cref="HttpInvocationOptions"/></returns>
|
||||
public HttpInvocationOptions WithQueryParam(string name, string value)
|
||||
{
|
||||
this.QueryString.Add(name, value);
|
||||
return this;
|
||||
|
|
@ -144,8 +146,8 @@ namespace Dapr.Client.Http
|
|||
/// This convenience method allow constructing a request with headers
|
||||
/// </summary>
|
||||
/// <param name="header">The header name and value you want to add</param>
|
||||
/// <returns>An updated instance of the same <see cref="HTTPExtension"/></returns>
|
||||
public HTTPExtension WithHeader(KeyValuePair<string, string> header)
|
||||
/// <returns>An updated instance of the same <see cref="HttpInvocationOptions"/></returns>
|
||||
public HttpInvocationOptions WithHeader(KeyValuePair<string, string> header)
|
||||
{
|
||||
this.Headers.Add(header.Key, header.Value);
|
||||
return this;
|
||||
|
|
@ -156,8 +158,8 @@ namespace Dapr.Client.Http
|
|||
/// </summary>
|
||||
/// <param name="name">Name of the header</param>
|
||||
/// <param name="value">Value of the header</param>
|
||||
/// <returns>An updated instance of the same <see cref="HTTPExtension"/></returns>
|
||||
public HTTPExtension WithHeader(string name, string value)
|
||||
/// <returns>An updated instance of the same <see cref="HttpInvocationOptions"/></returns>
|
||||
public HttpInvocationOptions WithHeader(string name, string value)
|
||||
{
|
||||
this.Headers.Add(name, value);
|
||||
return this;
|
||||
|
|
@ -166,8 +168,8 @@ namespace Dapr.Client.Http
|
|||
/// <summary>
|
||||
/// Uses <see cref="Constants.ContentTypeApplicationJson"/> as the content type for the request>
|
||||
/// </summary>
|
||||
/// <returns>An updated instance of the same <see cref="HTTPExtension"/></returns>
|
||||
public HTTPExtension WithJsonContentType()
|
||||
/// <returns>An updated instance of the same <see cref="HttpInvocationOptions"/></returns>
|
||||
public HttpInvocationOptions WithJsonContentType()
|
||||
{
|
||||
this.ContentType = Constants.ContentTypeApplicationJson;
|
||||
return this;
|
||||
|
|
@ -176,8 +178,8 @@ namespace Dapr.Client.Http
|
|||
/// <summary>
|
||||
/// Uses <see cref="Constants.ContentTypeApplicationGrpc"/> as the content type for the request>
|
||||
/// </summary>
|
||||
/// <returns>An updated instance of the same <see cref="HTTPExtension"/></returns>
|
||||
public HTTPExtension WithGrpcContentType()
|
||||
/// <returns>An updated instance of the same <see cref="HttpInvocationOptions"/></returns>
|
||||
public HttpInvocationOptions WithGrpcContentType()
|
||||
{
|
||||
this.ContentType = Constants.ContentTypeApplicationGrpc;
|
||||
return this;
|
||||
|
|
@ -4,9 +4,7 @@
|
|||
// ------------------------------------------------------------
|
||||
namespace Dapr.Client
|
||||
{
|
||||
using Dapr.Client.Http;
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents the exception thrown when Service Invocation via Dapr encounters an error
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@
|
|||
|
||||
namespace Dapr.Client
|
||||
{
|
||||
using Dapr.Client;
|
||||
using Dapr.Client.Http;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an Invoke Request used for service invocation
|
||||
/// </summary>
|
||||
|
|
@ -37,8 +34,8 @@ namespace Dapr.Client
|
|||
public TRequest Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP extension info.
|
||||
/// Gets or sets the HTTP options.
|
||||
/// </summary>
|
||||
public HTTPExtension HttpExtension { get; set; }
|
||||
public HttpInvocationOptions HttpOptions { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ namespace Dapr.Client
|
|||
{
|
||||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using Dapr.Client;
|
||||
using Dapr.Client.Http;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a response returned by service invocation
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Dapr.Client.Http;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace Dapr.Client.Test
|
||||
{
|
||||
public class HTTPExtensionTests
|
||||
{
|
||||
[Fact]
|
||||
public void HTTPExtension_HttpVerb_FluentMethods_CreateInstanceWithRightMethod()
|
||||
{
|
||||
foreach (var key in Enum.GetValues(typeof(HTTPVerb)))
|
||||
{
|
||||
HTTPExtension result = null;
|
||||
switch ((HTTPVerb)key)
|
||||
{
|
||||
case HTTPVerb.Get:
|
||||
result = HTTPExtension.UsingGet();
|
||||
break;
|
||||
case HTTPVerb.Head:
|
||||
result = HTTPExtension.UsingHead();
|
||||
break;
|
||||
case HTTPVerb.Post:
|
||||
result = HTTPExtension.UsingPost();
|
||||
break;
|
||||
case HTTPVerb.Put:
|
||||
result = HTTPExtension.UsingPut();
|
||||
break;
|
||||
case HTTPVerb.Delete:
|
||||
result = HTTPExtension.UsingDelete();
|
||||
break;
|
||||
case HTTPVerb.Connect:
|
||||
result = HTTPExtension.UsingConnect();
|
||||
break;
|
||||
case HTTPVerb.Options:
|
||||
result = HTTPExtension.UsingOptions();
|
||||
break;
|
||||
case HTTPVerb.Trace:
|
||||
result = HTTPExtension.UsingTrace();
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
result.Verb.Should().BeEquivalentTo((HTTPVerb)key);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HTTPExtension_QueryString_FluentMethods_CreateInstanceWithRightPayload()
|
||||
{
|
||||
var request = HTTPExtension
|
||||
.UsingPost()
|
||||
.WithQueryParam("key1", "value1")
|
||||
.WithQueryParam("key2", "value2")
|
||||
.WithQueryParam(new KeyValuePair<string, string>("key3", "value3"));
|
||||
|
||||
request.QueryString["key1"].Should().Be("value1");
|
||||
request.QueryString["key2"].Should().Be("value2");
|
||||
request.QueryString["key3"].Should().Be("value3");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HTTPExtension_Headers_FluentMethods_CreateInstanceWithRightPayload()
|
||||
{
|
||||
var request = HTTPExtension
|
||||
.UsingPost()
|
||||
.WithHeader("key1", "value1")
|
||||
.WithHeader("key2", "value2")
|
||||
.WithHeader(new KeyValuePair<string, string>("key3", "value3"));
|
||||
|
||||
request.Headers["key1"].Should().Be("value1");
|
||||
request.Headers["key2"].Should().Be("value2");
|
||||
request.Headers["key3"].Should().Be("value3");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
using GrpcVerb = Dapr.Client.Autogen.Grpc.v1.HTTPExtension.Types.Verb;
|
||||
|
||||
namespace Dapr.Client.Test
|
||||
{
|
||||
public class HttpInvocationOptionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void HttpInvocationOptions_HttpMethod_FluentMethods_CreateInstanceWithRightMethod()
|
||||
{
|
||||
// We have a convenience method for each of the enum values in the .proto except "None"
|
||||
foreach (var key in Enum.GetValues(typeof(GrpcVerb)).Cast<GrpcVerb>())
|
||||
{
|
||||
if (key == GrpcVerb.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var result = key switch
|
||||
{
|
||||
GrpcVerb.Get => HttpInvocationOptions.UsingGet(),
|
||||
GrpcVerb.Head => HttpInvocationOptions.UsingHead(),
|
||||
GrpcVerb.Post => HttpInvocationOptions.UsingPost(),
|
||||
GrpcVerb.Put => HttpInvocationOptions.UsingPut(),
|
||||
GrpcVerb.Delete => HttpInvocationOptions.UsingDelete(),
|
||||
GrpcVerb.Connect => HttpInvocationOptions.UsingConnect(),
|
||||
GrpcVerb.Options => HttpInvocationOptions.UsingOptions(),
|
||||
GrpcVerb.Trace => HttpInvocationOptions.UsingTrace(),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
result.Method.Method.ToUpperInvariant().Should().BeEquivalentTo(key.ToString().ToUpperInvariant());
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HttpInvocationOptions_QueryString_FluentMethods_CreateInstanceWithRightPayload()
|
||||
{
|
||||
var options = HttpInvocationOptions
|
||||
.UsingPost()
|
||||
.WithQueryParam("key1", "value1")
|
||||
.WithQueryParam("key2", "value2")
|
||||
.WithQueryParam(new KeyValuePair<string, string>("key3", "value3"));
|
||||
|
||||
options.QueryString["key1"].Should().Be("value1");
|
||||
options.QueryString["key2"].Should().Be("value2");
|
||||
options.QueryString["key3"].Should().Be("value3");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HttpInvocationOptions_Headers_FluentMethods_CreateInstanceWithRightPayload()
|
||||
{
|
||||
var options = HttpInvocationOptions
|
||||
.UsingPost()
|
||||
.WithHeader("key1", "value1")
|
||||
.WithHeader("key2", "value2")
|
||||
.WithHeader(new KeyValuePair<string, string>("key3", "value3"));
|
||||
|
||||
options.Headers["key1"].Should().Be("value1");
|
||||
options.Headers["key2"].Should().Be("value2");
|
||||
options.Headers["key3"].Should().Be("value3");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
namespace Dapr.Client.Test
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
|
@ -17,7 +16,6 @@ namespace Dapr.Client.Test
|
|||
using Dapr.Client;
|
||||
using Dapr.Client.Autogen.Grpc.v1;
|
||||
using Dapr.Client.Autogen.Test.Grpc.v1;
|
||||
using Dapr.Client.Http;
|
||||
using FluentAssertions;
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
|
@ -37,12 +35,12 @@ namespace Dapr.Client.Test
|
|||
.UseGrpcChannelOptions(new GrpcChannelOptions { HttpClient = httpClient })
|
||||
.Build();
|
||||
|
||||
var httpExtension = Http.HTTPExtension
|
||||
var httpOptions = HttpInvocationOptions
|
||||
.UsingPost()
|
||||
.WithQueryParam("key1", "value1")
|
||||
.WithQueryParam("key2", "value2");
|
||||
|
||||
var task = daprClient.InvokeMethodAsync<Response>("app1", "mymethod", httpExtension);
|
||||
var task = daprClient.InvokeMethodAsync<Response>("app1", "mymethod", httpOptions);
|
||||
|
||||
// Get Request and validate
|
||||
httpClient.Requests.TryDequeue(out var entry).Should().BeTrue();
|
||||
|
|
@ -85,7 +83,7 @@ namespace Dapr.Client.Test
|
|||
.UseGrpcChannelOptions(new GrpcChannelOptions { HttpClient = httpClient })
|
||||
.Build();
|
||||
|
||||
// httpExtension not specified
|
||||
// httpOptions not specified
|
||||
var task = daprClient.InvokeMethodAsync<Response>("app1", "mymethod");
|
||||
|
||||
// Get Request and validate
|
||||
|
|
@ -109,12 +107,12 @@ namespace Dapr.Client.Test
|
|||
.UseGrpcChannelOptions(new GrpcChannelOptions { HttpClient = httpClient })
|
||||
.Build();
|
||||
|
||||
var httpExtension = Http.HTTPExtension
|
||||
var httpOptions = HttpInvocationOptions
|
||||
.UsingPost()
|
||||
.WithHeader("Authorization", "Bearer foo")
|
||||
.WithHeader("X-Custom", "bar");
|
||||
|
||||
var task = daprClient.InvokeMethodAsync<Response>("app1", "mymethod", httpExtension);
|
||||
var task = daprClient.InvokeMethodAsync<Response>("app1", "mymethod", httpOptions);
|
||||
|
||||
// Get Request and validate
|
||||
httpClient.Requests.TryDequeue(out var entry).Should().BeTrue();
|
||||
|
|
@ -389,11 +387,11 @@ namespace Dapr.Client.Test
|
|||
|
||||
var invokeRequest = new Request() { RequestParameter = "Hello " };
|
||||
var invokedResponse = new Response { Name = "Look, I was invoked!" };
|
||||
var httpExtension = Http.HTTPExtension
|
||||
var httpOptions = HttpInvocationOptions
|
||||
.UsingPut()
|
||||
.WithQueryParam("key1", "value1");
|
||||
|
||||
var task = daprClient.InvokeMethodAsync<Request, Response>("test", "test1", invokeRequest, httpExtension);
|
||||
var task = daprClient.InvokeMethodAsync<Request, Response>("test", "test1", invokeRequest, httpOptions);
|
||||
|
||||
// Get Request and validate
|
||||
httpClient.Requests.TryDequeue(out var entry).Should().BeTrue();
|
||||
|
|
|
|||
Loading…
Reference in New Issue