Skip to content

Commit 906f44e

Browse files
WhitWaldodivzi-p
authored andcommitted
Adding instance-based CreateInvokableHttpClient (dapr#1319)
This PR takes the implementation of the static method and puts it into the DaprClient instance, pulling from the existing apiTokenHeader on the instance to populate the daprApiToken, pulling the endpoint from the instance's httpEndpoint value and accepting only an appId argument so as to specify the ID of the Dapr app to connect to and place in the resulting URI. --------- Signed-off-by: Whit Waldo <[email protected]> Signed-off-by: Divya Perumal <[email protected]>
1 parent 781fe32 commit 906f44e

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed

src/Dapr.Client/DaprClient.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public abstract class DaprClient : IDisposable
5858
/// The client will read the <see cref="HttpRequestMessage.RequestUri" /> property, and
5959
/// interpret the hostname as the destination <c>app-id</c>. The <see cref="HttpRequestMessage.RequestUri" />
6060
/// property will be replaced with a new URI with the authority section replaced by <paramref name="daprEndpoint" />
61-
/// and the path portion of the URI rewitten to follow the format of a Dapr service invocation request.
61+
/// and the path portion of the URI rewritten to follow the format of a Dapr service invocation request.
6262
/// </para>
6363
/// </summary>
6464
/// <param name="appId">
@@ -448,6 +448,30 @@ public HttpRequestMessage CreateInvokeMethodRequest<TRequest>(string appId, stri
448448
/// <returns>A <see cref="Task{T}" /> that will return the value when the operation has completed.</returns>
449449
public abstract Task<HttpResponseMessage> InvokeMethodWithResponseAsync(HttpRequestMessage request, CancellationToken cancellationToken = default);
450450

451+
#nullable enable
452+
/// <summary>
453+
/// <para>
454+
/// Creates an <see cref="HttpClient"/> that can be used to perform Dapr service invocation using <see cref="HttpRequestMessage"/>
455+
/// objects.
456+
/// </para>
457+
/// <para>
458+
/// The client will read the <see cref="HttpRequestMessage.RequestUri" /> property, and
459+
/// interpret the hostname as the destination <c>app-id</c>. The <see cref="HttpRequestMessage.RequestUri" />
460+
/// property will be replaced with a new URI with the authority section replaced by the HTTP endpoint value
461+
/// and the path portion of the URI rewritten to follow the format of a Dapr service invocation request.
462+
/// </para>
463+
/// </summary>
464+
/// <param name="appId">
465+
/// An optional <c>app-id</c>. If specified, the <c>app-id</c> will be configured as the value of
466+
/// <see cref="HttpClient.BaseAddress" /> so that relative URIs can be used. It is mandatory to set this parameter if your app-id contains at least one upper letter.
467+
/// If some requests use absolute URL with an app-id which contains at least one upper letter, it will not work, the workaround is to create one HttpClient for each app-id with the app-ip parameter set.
468+
/// </param>
469+
/// <returns>An <see cref="HttpClient" /> that can be used to perform service invocation requests.</returns>
470+
/// <remarks>
471+
/// </remarks>
472+
public abstract HttpClient CreateInvokableHttpClient(string? appId = null);
473+
#nullable disable
474+
451475
/// <summary>
452476
/// Perform service invocation using the request provided by <paramref name="request" />. If the response has a non-success
453477
/// status an exception will be thrown.

src/Dapr.Client/DaprClientGrpc.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,31 @@ public override async Task<HttpResponseMessage> InvokeMethodWithResponseAsync(Ht
450450
}
451451
}
452452

453+
/// <summary>
454+
/// <para>
455+
/// Creates an <see cref="HttpClient"/> that can be used to perform Dapr service invocation using <see cref="HttpRequestMessage"/>
456+
/// objects.
457+
/// </para>
458+
/// <para>
459+
/// The client will read the <see cref="HttpRequestMessage.RequestUri" /> property, and
460+
/// interpret the hostname as the destination <c>app-id</c>. The <see cref="HttpRequestMessage.RequestUri" />
461+
/// property will be replaced with a new URI with the authority section replaced by the instance's <see cref="httpEndpoint"/> value
462+
/// and the path portion of the URI rewritten to follow the format of a Dapr service invocation request.
463+
/// </para>
464+
/// </summary>
465+
/// <param name="appId">
466+
/// An optional <c>app-id</c>. If specified, the <c>app-id</c> will be configured as the value of
467+
/// <see cref="HttpClient.BaseAddress" /> so that relative URIs can be used. It is mandatory to set this parameter if your app-id contains at least one upper letter.
468+
/// If some requests use absolute URL with an app-id which contains at least one upper letter, it will not work, the workaround is to create one HttpClient for each app-id with the app-ip parameter set.
469+
/// </param>
470+
/// <returns>An <see cref="HttpClient" /> that can be used to perform service invocation requests.</returns>
471+
/// <remarks>
472+
/// </remarks>
473+
#nullable enable
474+
public override HttpClient CreateInvokableHttpClient(string? appId = null) =>
475+
DaprClient.CreateInvokeHttpClient(appId, this.httpEndpoint?.AbsoluteUri, this.apiTokenHeader?.Value);
476+
#nullable disable
477+
453478
public async override Task InvokeMethodAsync(HttpRequestMessage request, CancellationToken cancellationToken = default)
454479
{
455480
ArgumentVerifier.ThrowIfNull(request, nameof(request));
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// ------------------------------------------------------------------------
2+
// Copyright 2024 The Dapr Authors
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
// Unless required by applicable law or agreed to in writing, software
8+
// distributed under the License is distributed on an "AS IS" BASIS,
9+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
// See the License for the specific language governing permissions and
11+
// limitations under the License.
12+
// ------------------------------------------------------------------------
13+
14+
using System;
15+
using Xunit;
16+
17+
namespace Dapr.Client
18+
{
19+
public partial class DaprClientTest
20+
{
21+
[Fact]
22+
public void CreateInvokableHttpClient_WithAppId_FromDaprClient()
23+
{
24+
var daprClient = new MockClient().DaprClient;
25+
var client = daprClient.CreateInvokableHttpClient(appId: "bank");
26+
Assert.Equal("http://bank/", client.BaseAddress.AbsoluteUri);
27+
}
28+
29+
[Fact]
30+
public void CreateInvokableHttpClient_InvalidAppId_FromDaprClient()
31+
{
32+
var daprClient = new MockClient().DaprClient;
33+
var ex = Assert.Throws<ArgumentException>(() =>
34+
{
35+
// The appId needs to be something that can be used as hostname in a URI.
36+
_ = daprClient.CreateInvokableHttpClient(appId: "");
37+
});
38+
39+
Assert.Contains("The appId must be a valid hostname.", ex.Message);
40+
Assert.IsType<UriFormatException>(ex.InnerException);
41+
}
42+
43+
[Fact]
44+
public void CreateInvokableHttpClient_WithoutAppId_FromDaprClient()
45+
{
46+
var daprClient = new MockClient().DaprClient;
47+
48+
var client = daprClient.CreateInvokableHttpClient();
49+
Assert.Null(client.BaseAddress);
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)