Azure / azure-functions-durable-extension

Durable Task Framework extension for Azure Functions
MIT License
715 stars 270 forks source link

Durable Function Http API calls error when using route prefix #2927

Open simonmalletrc opened 2 weeks ago

simonmalletrc commented 2 weeks ago

Description

First off, in local development everything is working fine. Now, we deploy our durable function in a container using AKS. We use ingress rules to route traffic from dev-services.site.com/wam/data-syncer-api/ to the specific container hosting the durable function. the ingress rules has a rewrite path

  azfuncwim:
    enable_regex: true
    path: '/wam/data-syncer-api(/|$)(.*)'
    rewrite_path_to: '/$2'

I also add that prefix to environment variable DFM_INGRESS_ROUTE_PREFIX = wam/data-syncer-api

Once deployed, the durable function is accessible properly but we are having trouble using the built-in http endpoints for orchestrators.

For example, https://dev-services.site.com/wam/data-syncer-api/orchestrators/myapp/42 returns

{"id":"ImportSinglePlaylist","purgeHistoryDeleteUri":"http://dev-services.site.com/runtime/webhooks/durabletask/instances/ImportSinglePlaylist?code=longcodehere","sendEventPostUri":"http://dev-services.site.com/runtime/webhooks/durabletask/instances/ImportSinglePlaylist/raiseEvent/{eventName}?code=longcodehere","statusQueryGetUri":"http://dev-services.site.com/runtime/webhooks/durabletask/instances/ImportSinglePlaylist?code=longcodehere","terminatePostUri":"http://dev-services.site.com/runtime/webhooks/durabletask/instances/ImportSinglePlaylist/terminate?reason={{text}}&code=longcodehere","suspendPostUri":"http://dev-services.site.com/runtime/webhooks/durabletask/instances/ImportSinglePlaylist/suspend?reason={{text}}&code=longcodehere","resumePostUri":"http://dev-services.site.com/runtime/webhooks/durabletask/instances/ImportSinglePlaylist/resume?reason={{text}}&code=longcodehere"}

As you can see the route prefix wam/data-syncer-api is not present in the orchestrator urls. If I try to manually ADD the prefix and call the route to view all instances

https://dev-services.site.com/wam/data-syncer-api/runtime/webhooks/durabletask/instances?code=longcodehere

{"Message":"One or more of the arguments submitted is incorrect","ExceptionMessage":"startIndex cannot be larger than length of string. (Parameter 'startIndex')","ExceptionType":"System.ArgumentOutOfRangeException","StackTrace":"   at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length)\n   at System.String.Substring(Int32 startIndex)\n   at Microsoft.Azure.WebJobs.Extensions.DurableTask.HttpApiHandler.HandleRequestAsync(HttpRequestMessage request) in D:\\a\\_work\\1\\s\\src\\WebJobs.Extensions.DurableTask\\HttpApiHandler.cs:line 298"}

How can we make the durable function orchestrator built-in http endpoints work if we have a route prefix?

Expected behavior

The following URL should show me the list of all running instances knowing that wam/data-syncer-api is a route prefix to the container https://dev-services.site.com/wam/data-syncer-api/runtime/webhooks/durabletask/instances?code=longcodehere

Actual behavior

an error appears

{"Message":"One or more of the arguments submitted is incorrect","ExceptionMessage":"startIndex cannot be larger than length of string. (Parameter 'startIndex')","ExceptionType":"System.ArgumentOutOfRangeException","StackTrace":"   at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length)\n   at System.String.Substring(Int32 startIndex)\n   at Microsoft.Azure.WebJobs.Extensions.DurableTask.HttpApiHandler.HandleRequestAsync(HttpRequestMessage request) in D:\\a\\_work\\1\\s\\src\\WebJobs.Extensions.DurableTask\\HttpApiHandler.cs:line 298"}

Relevant source code snippets

// insert code snippet here

Known workarounds

Create a custom endpoint to display the status and ignore the built-in endpoints...

App Details

Screenshots

If applicable, add screenshots to help explain your problem.

If deployed to Azure

We have access to a lot of telemetry that can help with investigations. Please provide as much of the following information as you can to help us investigate!

If you don't want to share your Function App or storage account name GitHub, please at least share the orchestration instance ID. Otherwise it's extremely difficult to look up information.

cgillum commented 2 days ago

Azure Functions doesn't support route prefixes for built-in HTTP APIs. There are a couple things you can consider to work around this:

  1. Use an HTTP forwarding / URL-rewriting to internally send the expected HTTP request route to the Functions host.
  2. Use HTTP-triggered functions and SDK methods to implement the same functionality as the built-in HTTP APIs.

I recommend the latter since it gives you the most control and flexibility.