Skip to content

Commit

Permalink
Update EventHub converter and unit tests (#1633, #1716, #1723, #1742)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Aishwarya Bhandari <aibhandari@microsoft.com>
  • Loading branch information
liliankasem and aishwaryabh committed Jul 24, 2023
1 parent 585b5fb commit aec4408
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 17 deletions.
27 changes: 17 additions & 10 deletions extensions/Worker.Extensions.EventHubs/src/EventDataConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;
using Azure.Messaging.EventHubs;
using Microsoft.Azure.Functions.Worker.Extensions.EventHubs;
using Microsoft.Azure.Functions.Worker.Extensions;

namespace Microsoft.Azure.Functions.Worker
{
/// <summary>
/// Converter to bind to <see cref="EventData" /> or <see cref="T:EventData[]" /> type parameters.
/// </summary>
[SupportsDeferredBinding]
[SupportedConverterType(typeof(EventData))]
[SupportedConverterType(typeof(EventData[]))]
[SupportedTargetType(typeof(EventData))]
[SupportedTargetType(typeof(EventData[]))]
internal class EventDataConverter : IInputConverter
{
public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
Expand All @@ -26,7 +30,7 @@ public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)
{
ModelBindingData binding => ConversionResult.Success(ConvertToEventData(binding)),
// Only array collections are currently supported, which matches the behavior of the in-proc extension.
CollectionModelBindingData collection => ConversionResult.Success(collection.ModelBindingDataArray
CollectionModelBindingData collection => ConversionResult.Success(collection.ModelBindingData
.Select(ConvertToEventData).ToArray()),
_ => ConversionResult.Unhandled()
};
Expand All @@ -40,19 +44,22 @@ public ValueTask<ConversionResult> ConvertAsync(ConverterContext context)

private EventData ConvertToEventData(ModelBindingData binding)
{
if (binding?.Source is not Constants.BindingSource)
if (binding is null)
{
throw new InvalidOperationException(
$"Unexpected binding source. Only '{Constants.BindingSource}' is supported.");
throw new ArgumentNullException(nameof(binding));
}

if (binding.ContentType != Constants.BinaryContentType)
if (binding.Source is not Constants.BindingSource)
{
throw new InvalidOperationException(
$"Unexpected content-type. Only '{Constants.BinaryContentType}' is supported.");
throw new InvalidBindingSourceException(binding.Source, Constants.BindingSource);
}

if (binding.ContentType is not Constants.BinaryContentType)
{
throw new InvalidContentTypeException(binding.ContentType, Constants.BinaryContentType);
}

return new EventData(AmqpAnnotatedMessage.FromBytes(binding.Content));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ namespace Microsoft.Azure.Functions.Worker
/// <summary>
/// Attribute used to mark a function that should be triggered by Event Hubs messages.
/// </summary>
[BindingCapabilities(KnownBindingCapabilities.FunctionLevelRetry)]
[AllowConverterFallback(true)]
[InputConverter(typeof(EventDataConverter))]
[ConverterFallbackBehavior(ConverterFallbackBehavior.Default)]
[BindingCapabilities(KnownBindingCapabilities.FunctionLevelRetry)]
public sealed class EventHubTriggerAttribute : TriggerBindingAttribute, ISupportCardinality
{
// Batch by default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@
<PackageReference Include="Azure.Messaging.EventHubs" Version="5.9.2" />
</ItemGroup>

<ItemGroup>
<SharedReference Include="..\..\Worker.Extensions.Shared\Worker.Extensions.Shared.csproj" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion samples/WorkerBindingSamples/EventHubs/EventDataSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public EventDataSamples(ILogger<EventDataSamples> logger)
/// </summary>
[Function(nameof(EventDataWithStringPropertiesFunction))]
public void EventDataWithStringPropertiesFunction(
[EventHubTrigger("queue", Connection = "EventHubConnection")]
[EventHubTrigger("queue", Connection = "EventHubConnection", IsBatched = false)]
EventData @event, string contentType, long offset)
{
// The ContentType property and the contentType parameter are the same.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,5 +386,71 @@
"properties": {}
}
]
},
{
"name": "EventDataFunctions",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "SampleApp.EventDataSamples.EventDataFunctions",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "event",
"direction": "In",
"type": "eventHubTrigger",
"eventHubName": "queue",
"connection": "EventHubConnection",
"cardinality": "One",
"properties": {
"supportsDeferredBinding": "True"
}
}
]
},
{
"name": "EventDataBatchFunction",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "SampleApp.EventDataSamples.EventDataBatchFunction",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "events",
"direction": "In",
"type": "eventHubTrigger",
"eventHubName": "queue",
"connection": "EventHubConnection",
"cardinality": "Many",
"properties": {
"supportsDeferredBinding": "True"
}
}
]
},
{
"name": "EventDataWithStringPropertiesFunction",
"scriptFile": "WorkerBindingSamples.dll",
"entryPoint": "SampleApp.EventDataSamples.EventDataWithStringPropertiesFunction",
"language": "dotnet-isolated",
"properties": {
"IsCodeless": false
},
"bindings": [
{
"name": "event",
"direction": "In",
"type": "eventHubTrigger",
"eventHubName": "queue",
"connection": "EventHubConnection",
"cardinality": "One",
"properties": {
"supportsDeferredBinding": "True"
}
}
]
}
]
3 changes: 3 additions & 0 deletions test/SdkE2ETests/PublishTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ private async Task RunPublishTestForSdkTypeBindings(string outputDir, string add
new Extension("EventGrid",
"Microsoft.Azure.WebJobs.Extensions.EventGrid.EventGridWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.EventGrid, Version=3.3.0.0, Culture=neutral, PublicKeyToken=014045d636e89289",
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.EventGrid.dll"),
new Extension("EventHubs",
"Microsoft.Azure.WebJobs.EventHubs.EventHubsWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.EventHubs, Version=5.4.0.0, Culture=neutral, PublicKeyToken=014045d636e89289",
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.EventHubs.dll"),
new Extension("Startup",
"Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.Startup, Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=551316b6919f366c",
@"./.azurefunctions/Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.dll"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public async Task ConvertAsync_ReturnsFailure_WrongContentType()
Assert.Equal(ConversionStatus.Failed, result.Status);
var output = result.Value as EventData;
Assert.Null(output);
Assert.IsType<InvalidOperationException>(result.Error);
Assert.Equal("Unexpected content-type 'application/json'. Only 'application/octet-stream' is supported.", result.Error.Message);
}

[Fact]
Expand All @@ -114,7 +114,7 @@ public async Task ConvertAsync_Batch_ReturnsFailure_WrongContentType()
Assert.Equal(ConversionStatus.Failed, result.Status);
var output = result.Value as EventData[];
Assert.Null(output);
Assert.IsType<InvalidOperationException>(result.Error);
Assert.Equal("Unexpected content-type 'application/json'. Only 'application/octet-stream' is supported.", result.Error.Message);
}

[Fact]
Expand All @@ -137,7 +137,7 @@ public async Task ConvertAsync_ReturnsFailure_WrongSource()
Assert.Equal(ConversionStatus.Failed, result.Status);
var output = result.Value as EventData;
Assert.Null(output);
Assert.IsType<InvalidOperationException>(result.Error);
Assert.Equal("Unexpected binding source 'some-other-source'. Only 'AzureEventHubsEventData' is supported.", result.Error.Message);
}

[Fact]
Expand All @@ -164,7 +164,7 @@ public async Task ConvertAsync_Batch_ReturnsFailure_WrongSource()
Assert.Equal(ConversionStatus.Failed, result.Status);
var output = result.Value as EventData[];
Assert.Null(output);
Assert.IsType<InvalidOperationException>(result.Error);
Assert.Equal("Unexpected binding source 'some-other-source'. Only 'AzureEventHubsEventData' is supported.", result.Error.Message);
}

private static void AssertEventData(EventData output)
Expand Down

0 comments on commit aec4408

Please sign in to comment.