From b66acf951edeb7355bf8e4d3a5f850638e72a167 Mon Sep 17 00:00:00 2001 From: Sarah Vu Date: Thu, 7 Dec 2023 11:31:44 -0800 Subject: [PATCH 1/3] add isBatched default value --- extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs b/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs index 6708f7593..bc79ca515 100644 --- a/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs +++ b/extensions/Worker.Extensions.Kafka/src/KafkaTriggerAttribute.cs @@ -130,6 +130,7 @@ public KafkaTriggerAttribute(string brokerList, string topic) /// /// Gets or sets the configuration to enable batch processing of events. Default value is "false". /// + [DefaultValue(false)] public bool IsBatched { get => _isBatched; From a004351e03dc816ea4b171a33fbd0e3f2c26aa46 Mon Sep 17 00:00:00 2001 From: Sarah Vu Date: Thu, 7 Dec 2023 14:43:34 -0800 Subject: [PATCH 2/3] bump and add release notes --- extensions/Worker.Extensions.Kafka/release_notes.md | 4 ++-- .../src/Worker.Extensions.Kafka.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/Worker.Extensions.Kafka/release_notes.md b/extensions/Worker.Extensions.Kafka/release_notes.md index e73c591ab..7a6d56c7a 100644 --- a/extensions/Worker.Extensions.Kafka/release_notes.md +++ b/extensions/Worker.Extensions.Kafka/release_notes.md @@ -4,6 +4,6 @@ - My change description (#PR/#issue) --> -### Microsoft.Azure.Functions.Worker.Extensions.Kafka +### Microsoft.Azure.Functions.Worker.Extensions.Kafka 3.10.1 -- +- Add `DefaultValue` attribute to Kafka Trigger's `IsBatched` prop to signal default cardinality value to source generators (#2139) diff --git a/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj b/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj index bbf3f596c..d72dba8fe 100644 --- a/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj +++ b/extensions/Worker.Extensions.Kafka/src/Worker.Extensions.Kafka.csproj @@ -5,7 +5,7 @@ Kafka extensions for .NET isolated functions - 3.10.0 + 3.10.1 false From 13ea1f258cf474e27b27775e6b18deae020c146c Mon Sep 17 00:00:00 2001 From: Sarah Vu Date: Mon, 11 Dec 2023 14:12:06 -0800 Subject: [PATCH 3/3] add kafka ut --- .../KafkaTests.cs | 149 ++++++++++++++++++ .../Sdk.Generator.Tests.csproj | 3 +- 2 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs diff --git a/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs new file mode 100644 index 000000000..e8a35e556 --- /dev/null +++ b/test/Sdk.Generator.Tests/FunctionMetadataProviderGeneratorTests/KafkaTests.cs @@ -0,0 +1,149 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.Azure.Functions.Worker.Sdk.Generators; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; + +namespace Microsoft.Azure.Functions.SdkGeneratorTests +{ + public partial class FunctionMetadataProviderGeneratorTests + { + public class KafkaTests + { + private readonly Assembly[] _referencedExtensionAssemblies; + + public KafkaTests() + { + // load all extensions used in tests (match extensions tested on E2E app? Or include ALL extensions?) + var abstractionsExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Abstractions.dll"); + var hostingExtension = Assembly.LoadFrom("Microsoft.Extensions.Hosting.dll"); + var diExtension = Assembly.LoadFrom("Microsoft.Extensions.DependencyInjection.dll"); + var hostingAbExtension = Assembly.LoadFrom("Microsoft.Extensions.Hosting.Abstractions.dll"); + var diAbExtension = Assembly.LoadFrom("Microsoft.Extensions.DependencyInjection.Abstractions.dll"); + var kafkaExtension = Assembly.LoadFrom("Microsoft.Azure.Functions.Worker.Extensions.Kafka.dll"); + + _referencedExtensionAssemblies = new[] + { + abstractionsExtension, + hostingExtension, + hostingAbExtension, + diExtension, + diAbExtension, + kafkaExtension + }; + } + + [Theory] + [InlineData(LanguageVersion.CSharp7_3)] + [InlineData(LanguageVersion.CSharp8)] + [InlineData(LanguageVersion.CSharp9)] + [InlineData(LanguageVersion.CSharp10)] + [InlineData(LanguageVersion.CSharp11)] + [InlineData(LanguageVersion.Latest)] + public async Task GenerateSimpleKafkaTriggerTest(LanguageVersion languageVersion) + { + string inputCode = """ + using System; + using Microsoft.Azure.Functions.Worker; + + namespace FunctionApp + { + public static class KafkaFunction + { + [Function(nameof(KafkaFunction))] + [FixedDelayRetry(5, "00:00:10")] + [KafkaOutput("LocalBroker", "stringTopicTenPartitions")] + public static string Run([KafkaTrigger("LocalBroker", "stringTopicTenPartitions", + ConsumerGroup = "$Default", AuthenticationMode = BrokerAuthenticationMode.Plain)] string input, + FunctionContext context) + { + throw new NotImplementedException(); + } + } + } + """; + + string expectedGeneratedFileName = $"GeneratedFunctionMetadataProvider.g.cs"; + string expectedOutput = """ + // + using System; + using System.Collections.Generic; + using System.Collections.Immutable; + using System.Text.Json; + using System.Threading.Tasks; + using Microsoft.Azure.Functions.Worker; + using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + + namespace TestProject + { + /// + /// Custom implementation that returns function metadata definitions for the current worker."/> + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class GeneratedFunctionMetadataProvider : IFunctionMetadataProvider + { + /// + public Task> GetFunctionMetadataAsync(string directory) + { + var metadataList = new List(); + var Function0RawBindings = new List(); + Function0RawBindings.Add(@"{""name"":""$return"",""type"":""kafka"",""direction"":""Out"",""brokerList"":""LocalBroker"",""topic"":""stringTopicTenPartitions""}"); + Function0RawBindings.Add(@"{""name"":""input"",""type"":""kafkaTrigger"",""direction"":""In"",""brokerList"":""LocalBroker"",""topic"":""stringTopicTenPartitions"",""consumerGroup"":""$Default"",""authenticationMode"":""Plain"",""cardinality"":""One"",""dataType"":""String""}"); + + var Function0 = new DefaultFunctionMetadata + { + Language = "dotnet-isolated", + Name = "KafkaFunction", + EntryPoint = "FunctionApp.KafkaFunction.Run", + RawBindings = Function0RawBindings, + Retry = new DefaultRetryOptions + { + MaxRetryCount = 5, + DelayInterval = TimeSpan.Parse("00:00:10") + }, + ScriptFile = "TestProject.dll" + }; + metadataList.Add(Function0); + + return Task.FromResult(metadataList.ToImmutableArray()); + } + } + + /// + /// Extension methods to enable registration of the custom implementation generated for the current worker. + /// + public static class WorkerHostBuilderFunctionMetadataProviderExtension + { + /// + /// Adds the GeneratedFunctionMetadataProvider to the service collection. + /// During initialization, the worker will return generated function metadata instead of relying on the Azure Functions host for function indexing. + /// + public static IHostBuilder ConfigureGeneratedFunctionMetadataProvider(this IHostBuilder builder) + { + builder.ConfigureServices(s => + { + s.AddSingleton(); + }); + return builder; + } + } + } + """; + + await TestHelpers.RunTestAsync( + _referencedExtensionAssemblies, + inputCode, + expectedGeneratedFileName, + expectedOutput, + languageVersion: languageVersion); + } + } + } +} diff --git a/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj b/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj index 8feb33d9a..340bba70c 100644 --- a/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj +++ b/test/Sdk.Generator.Tests/Sdk.Generator.Tests.csproj @@ -46,7 +46,8 @@ + - + \ No newline at end of file