Skip to content

Commit

Permalink
update by comment
Browse files Browse the repository at this point in the history
  • Loading branch information
nytian committed Oct 8, 2024
1 parent 376fb69 commit 221138f
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 60 deletions.
10 changes: 9 additions & 1 deletion src/WebJobs.Extensions.DurableTask/Bindings/BindingHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public string DurableOrchestrationClientToString(IDurableOrchestrationClient cli
ConnectionName = attr.ConnectionName,
RpcBaseUrl = localRpcAddress,
RequiredQueryStringParameters = this.config.HttpApiHandler.GetUniversalQueryStrings(),
BaseUrl = this.config.HttpApiHandler.GetBaseUrl(),
HttpBaseUrl = this.config.HttpApiHandler.GetBaseUrl(),
});
}

Expand Down Expand Up @@ -131,6 +131,14 @@ private class OrchestrationClientInputData
/// </summary>
[JsonProperty("rpcBaseUrl")]
public string? RpcBaseUrl { get; set; }

/// <summary>
/// The base URL of the Azure Functions host, used in the out-of-proc model.
/// This URL is sent by the client binding object to the Durable Worker extension,
/// allowing the extension to know the host's base URL for constructing complete URLs.
/// </summary>
[JsonProperty("HttpBaseUrl")]
public string? HttpBaseUrl { get; set; }
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
}

DurableTaskClient client = this.clientProvider.GetClient(endpoint, inputData?.taskHubName, inputData?.connectionName);
client = new FunctionsDurableTaskClient(client, inputData!.requiredQueryStringParameters, inputData!.baseUrl);
client = new FunctionsDurableTaskClient(client, inputData!.requiredQueryStringParameters, inputData!.httpBaseUrl);
return new ValueTask<ConversionResult>(ConversionResult.Success(client));
}
catch (Exception innerException)
Expand All @@ -62,5 +62,5 @@ public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
}

// Serializer is case-sensitive and incoming JSON properties are camel-cased.
private record DurableClientInputData(string rpcBaseUrl, string taskHubName, string connectionName, string requiredQueryStringParameters, string baseUrl);
private record DurableClientInputData(string rpcBaseUrl, string taskHubName, string connectionName, string requiredQueryStringParameters, string httpBaseUrl);
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,6 @@ private static ObjectSerializer GetObjectSerializer(HttpResponseData response)

private static string? GetBaseUrl(DurableTaskClient client)
{
return client is FunctionsDurableTaskClient functions ? functions.BaseUrl : null;
return client is FunctionsDurableTaskClient functions ? functions.HttpBaseUrl : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ internal sealed class FunctionsDurableTaskClient : DurableTaskClient
{
private readonly DurableTaskClient inner;

public FunctionsDurableTaskClient(DurableTaskClient inner, string? queryString, string? baseUrl)
public FunctionsDurableTaskClient(DurableTaskClient inner, string? queryString, string? httpBaseUrl)
: base(inner.Name)
{
this.inner = inner;
this.QueryString = queryString;
this.BaseUrl = baseUrl;
this.HttpBaseUrl = httpBaseUrl;
}

public string? QueryString { get; }
public string? BaseUrl { get; }
public string? HttpBaseUrl { get; }
public override DurableEntityClient Entities => this.inner.Entities;

public override ValueTask DisposeAsync()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System.Security.Claims;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask.Client;
using Microsoft.DurableTask.Client.Grpc;
using Moq;

namespace Microsoft.Azure.Functions.Worker.Tests
Expand All @@ -24,7 +22,7 @@ private FunctionsDurableTaskClient GetTestFunctionsDurableTaskClient(string? bas
It.IsAny<string>(), It.IsAny<TerminateInstanceOptions>(), It.IsAny<CancellationToken>())).Returns(completedTask);

DurableTaskClient durableClient = durableClientMock.Object;
FunctionsDurableTaskClient client = new FunctionsDurableTaskClient(durableClient, queryString: null, baseUrl: baseUrl);
FunctionsDurableTaskClient client = new FunctionsDurableTaskClient(durableClient, queryString: null, httpBaseUrl: baseUrl);
return client;
}

Expand Down Expand Up @@ -62,7 +60,7 @@ public async void TerminateDoesNotThrow()
[Fact]
public void CreateHttpManagementPayload_WithBaseUrl()
{
string BaseUrl = "http://localhost:7071/runtime/webhooks/durabletask";
const string BaseUrl = "http://localhost:7071/runtime/webhooks/durabletask";
FunctionsDurableTaskClient client = this.GetTestFunctionsDurableTaskClient(BaseUrl);
string instanceId = "testInstanceIdWithHostBaseUrl";

Expand All @@ -77,13 +75,16 @@ public void CreateHttpManagementPayload_WithBaseUrl()
[Fact]
public void CreateHttpManagementPayload_WithHttpRequestData()
{
string requestUrl = "http://localhost:7075/orchestrators/E1_HelloSequence";
const string requestUrl = "http://localhost:7075/orchestrators/E1_HelloSequence";
FunctionsDurableTaskClient client = this.GetTestFunctionsDurableTaskClient();
string instanceId = "testInstanceIdWithRequest";
var context = new TestFunctionContext();
var request = new TestHttpRequestData(context, new Uri(requestUrl));

dynamic payload = client.CreateHttpManagementPayload(instanceId, request);
// Create mock HttpRequestData object.
var mockFunctionContext = new Mock<FunctionContext>();
var mockHttpRequestData = new Mock<HttpRequestData>(mockFunctionContext.Object);
mockHttpRequestData.SetupGet(r => r.Url).Returns(new Uri(requestUrl));

dynamic payload = client.CreateHttpManagementPayload(instanceId, mockHttpRequestData.Object);

AssertHttpManagementPayload(payload, "http://localhost:7075/runtime/webhooks/durabletask", instanceId);
}
Expand All @@ -99,49 +100,4 @@ private static void AssertHttpManagementPayload(dynamic payload, string BaseUrl,
Assert.Equal($"{BaseUrl}/instances/{instanceId}/resume?reason={{{{text}}}}", payload.resumePostUri);
}
}

/// <summary>
/// A minimal implementation of FunctionContext for testing purposes.
/// It's used to create a TestHttpRequestData instance, which requires a FunctionContext.
/// </summary>
public class TestFunctionContext : FunctionContext
{
public override string InvocationId => throw new NotImplementedException();
public override string FunctionId => throw new NotImplementedException();
public override TraceContext TraceContext => throw new NotImplementedException();
public override BindingContext BindingContext => throw new NotImplementedException();
public override RetryContext RetryContext => throw new NotImplementedException();
public override IServiceProvider InstanceServices { get; set; } = new EmptyServiceProvider();
public override FunctionDefinition FunctionDefinition => throw new NotImplementedException();
public override IDictionary<object, object> Items { get; set; } = new Dictionary<object, object>();
public override IInvocationFeatures Features => throw new NotImplementedException();
}

/// <summary>
/// A minimal implementation of IServiceProvider for testing purposes.
/// </summary>
public class EmptyServiceProvider : IServiceProvider
{
public object GetService(Type serviceType) => null;
}

// <summary>
/// A test implementation of HttpRequestData used for unit testing.
/// This class allows us to create instances of HttpRequestData, which is normally abstract.
/// </summary>
public class TestHttpRequestData : HttpRequestData
{
public TestHttpRequestData(FunctionContext functionContext, Uri url) : base(functionContext)
{
Url = url;
}

public override Stream Body => throw new NotImplementedException();
public override HttpHeadersCollection Headers => throw new NotImplementedException();
public override IReadOnlyCollection<IHttpCookie> Cookies => throw new NotImplementedException();
public override Uri Url { get; }
public override IEnumerable<ClaimsIdentity> Identities => throw new NotImplementedException();
public override string Method => throw new NotImplementedException();
public override HttpResponseData CreateResponse() => throw new NotImplementedException();
}
}

0 comments on commit 221138f

Please sign in to comment.