Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
419 stars 182 forks source link

IotHubTrigger --> EventHubTrigger so many problems with upgrade from 3.1 to .net 6 isolated. #1064

Closed MacMcDell closed 1 year ago

MacMcDell commented 2 years ago

I have a legacy/older running 3.1 azure function IOThubTrigger running using .net 3.1. Trying to upgrade the project to .net 6 Isolated. Running into so many issues with reading the EventData objects.

Old Function Signature which is working 100%

[FunctionName(nameof(IoTHubMessageHandlerFnc))]
        public async Task Run(
            [IoTHubTrigger("messages/events", Connection = "Service:IoTHubConnectionString")]EventData[] iotHubMessages )

When the function executes from the listener I get the following payload: old

     local.settings.json file 
     "Values" :{
     "Service:IoTHubConnectionString": "EventHubCompatibleEndpointFoundOnAzureIotHubApplicationIncludingEntityPath",```
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="4.1.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.1" />

.Net6 Isolated 4.x azure function

The Problem:

Trying to run the application results in all EventData being empty. I subscribe to the same IOTHub endpoint using Microsoft.Azure.Functions.Worker.Extenstions.EventHubs V4.3 and the eventData is completely empty. I get the message batches but cannot read or parse them at all as it seems they are empty upon arrival??! image

Attempted resolutions:

Upgraded Microsoft.Azure.Functions.Worker.Extenstions.EventHubs to V5.1.0 Result: Exception is thrown on the Event Hub-compatible endpoint (inlcudes EntityPath), with the following message Azure.Messaging.EventHubs: The path to an Event Hub may be specified as part of the connection string or as a separate value, but not both. Please verify that your connection string does not have theEntityPathtoken if you are passing an explicit Event Hub name. (Parameter 'connectionString').

Omitting EntityPath from the connection string results in 'The messaging entity 'sb://path.servicebus.windows.net/messages/events' could not be found. To know more visit https://aka.ms/sbResourceMgrExceptions. (messages/events)'

There does not appear to be any documentation on how to use a different connection string since Connection is still the param in the Ctor of EventHubTrigger

        /// Gets or sets the optional app setting name that contains the Event Hub connection string. If missing, tries to use a registered event hub receiver.
        /// </summary>
        public string? Connection { get; set; }

Attempts at using Shared Access Policy for IOTHubOwner also fail along similar lines.

Service:IoTHubConnectionString: "HostName={hostname};SharedAccessKeyName={};SharedAccessKey={}" Error: Azure.Messaging.EventHubs: The connection string used for an Event Hub client must specify the Event Hubs namespace host, and either a Shared Access Key (both the name and value) or Shared Access Signature to be v alid. The path to an Event Hub must be included in the connection string or specified separately. (Parameter 'connectionString')..... :(

SETUP

.csproj

 <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <LangVersion>preview</LangVersion>
    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Azure.Messaging.EventHubs" Version="5.7.2" />
    <PackageReference Include="Microsoft.Azure.Cosmos" Version="3.30.1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.0.0-preview1" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ApplicationInsights" Version="1.0.0-preview4" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.EventHubs" Version="5.1.0" /> 
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.1.0" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.7.0" OutputItemType="Analyzer" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.8.0" />
    <PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.33" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.21.0" />
  </ItemGroup>
  <ItemGroup>
.cs function
  [Function(nameof(IoTHubMessageHandlerFnc))]
        public async Task Run(
            [EventHubTrigger("messages/events", ConsumerGroup = "vscode",  Connection = "CapService:IoTHubConnectionString")] EventData[] iotHubMessages)
        {
local.settings.json
... 
"CapService:IoTHubConnectionString": "Endpoint=sb://{name}/;SharedAccessKeyName={keyName};SharedAccessKey={AccessKey}};EntityPath={EntityPath}",
....

I am at a complete loss at this point on how to get my currently running event into my isolated .net6 project. I can't find any EventHubTrigger code samples that refer to dropping EntityPath from the connection string (Note this only breaks in V5.1.0 of Extensions.EventHubs)
Any advice or help would be greatly appreciated.

MacMcDell commented 2 years ago

I found this link with exactly the same issues as I am having, however the resolution is not working for me. Replacing the EventHubName with whatever is in EntityPath ... in my case is application name iothb-ingress-pr resulted in the function working but the events are still all empty of any content. Running the same app as 3.1 give s me the messages. System Properties is just a single kv of ContentType , "application-json". image

MacMcDell commented 2 years ago

I was able to figure out from another ticket to change my inputs body from EventData[] to Byte[][] or string[] . This has enabled me to obtain the payloads I need to continue working BUT it means I have lost all features of EventData . I feel like either something is very wrong here or this needs to be better documented somehow. image

kshyju commented 2 years ago

Binding to the EventData type is not yet supported in the isolated model. But you can bind the messages to string array or an array of POCO (which has a matching structure of the message payload sent to the event hub).

Obtaining the meta properties of the message is also supported. Please refer the event hub trigger example in our samples. Let us know if you run into any issues.

ghost commented 2 years ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.