11using Intent . Engine ;
2+ using Intent . Modelers . Eventing . Api ;
3+ using Intent . Modelers . Services . Api ;
24using Intent . Modelers . Services . EventInteractions ;
35using Intent . Modules . AzureFunctions . Settings ;
46using Intent . Modules . Common ;
57using Intent . Modules . Common . CSharp . Api ;
68using Intent . Modules . Common . CSharp . Builder ;
9+ using Intent . Modules . Common . CSharp . Configuration ;
10+ using Intent . Modules . Common . CSharp . DependencyInjection ;
711using Intent . Modules . Common . CSharp . Templates ;
812using Intent . Modules . Common . Templates ;
913using Intent . Modules . Common . Types . Api ;
14+ using Intent . Modules . Common . UnitOfWork . Shared ;
15+ using Intent . Modules . Eventing . AzureQueueStorage ;
16+ using Intent . Modules . Eventing . AzureQueueStorage . Settings ;
17+ using Intent . Modules . Eventing . AzureQueueStorage . Templates ;
18+ using Intent . Modules . Eventing . Contracts . Templates ;
1019using Intent . RoslynWeaver . Attributes ;
1120using Intent . Templates ;
1221using System ;
1322using System . Collections . Generic ;
1423using System . Linq ;
24+ using static System . Net . Mime . MediaTypeNames ;
1525
1626[ assembly: DefaultIntentManaged ( Mode . Fully ) ]
1727[ assembly: IntentTemplate ( "Intent.ModuleBuilder.CSharp.Templates.CSharpTemplatePartial" , Version = "1.0" ) ]
@@ -26,19 +36,86 @@ public partial class AzureFunctionConsumerTemplate : CSharpTemplateBase<Integrat
2636 [ IntentManaged ( Mode . Fully , Body = Mode . Ignore ) ]
2737 public AzureFunctionConsumerTemplate ( IOutputTarget outputTarget , IntegrationEventHandlerModel model ) : base ( TemplateId , outputTarget , model )
2838 {
39+ AddNugetDependency ( NugetPackages . MicrosoftAzureFunctionsWorkerExtensionsStorageQueues ( outputTarget ) ) ;
40+
2941 CSharpFile = new CSharpFile ( this . GetNamespace ( ) , this . GetRelativeLocation ( ) )
3042 . AddClass ( GetFunctionName ( ) , @class =>
3143 {
44+ @class . AddField ( UseType ( "System.Text.Json.JsonSerializerOptions" ) , "_serializerOptions" , @field =>
45+ {
46+ @field . PrivateReadOnly ( ) ;
47+ } ) ;
48+
3249 @class . AddConstructor ( ctor =>
3350 {
34- ctor . AddParameter ( "string" , "exampleParam" , param =>
51+ ctor . AddParameter ( this . GetAzureQueueStorageEventDispatcherInterfaceName ( ) , "dispatcher" , param => param . IntroduceReadonlyField ( ) ) ;
52+ ctor . AddParameter ( UseType ( $ "Microsoft.Extensions.Logging.ILogger<{ @class . Name } >") , "logger" , param => param . IntroduceReadonlyField ( ) ) ;
53+ ctor . AddParameter ( this . GetEventBusInterfaceName ( ) , "eventBus" , param => param . IntroduceReadonlyField ( ) ) ;
54+ ctor . AddParameter ( UseType ( "System.IServiceProvider" ) , "serviceProvider" , param => param . IntroduceReadonlyField ( ) ) ;
55+
56+ ctor . AddObjectInitStatement ( "_serializerOptions" , new CSharpObjectInitializerBlock ( "new JsonSerializerOptions" )
57+ . AddAssignmentStatement ( "PropertyNamingPolicy" , new CSharpStatement ( "JsonNamingPolicy.CamelCase" ) )
58+ . AddAssignmentStatement ( "PropertyNameCaseInsensitive" , new CSharpStatement ( "true" ) ) . WithSemicolon ( ) ) ;
59+ } ) ;
60+
61+ @class . AddMethod ( UseType ( "System.Threading.Tasks.Task" ) , "Run" , method =>
62+ {
63+ method . Async ( ) ;
64+ method . AddAttribute ( "Function" , attr => attr . AddArgument ( $@ """{ @class . Name } """));
65+ method.AddParameter(this.GetAzureQueueStorageEnvelopeName(), " message", param =>
66+ {
67+ param . AddAttribute ( UseType ( "Microsoft.Azure.Functions.Worker.QueueTrigger" ) , attr =>
68+ {
69+ var messages = Model . IntegrationEventSubscriptions ( ) . Select ( s => s . Element . AsMessageModel ( ) ) ;
70+ var commandModels = Model . IntegrationCommandSubscriptions ( ) . Select ( s => s . Element . AsIntegrationCommandModel ( ) ) ;
71+
72+ var queueName = messages is not null && messages . Any ( ) ? HelperExtensions . GetMessageQueue ( messages . First ( ) ) :
73+ commandModels is not null && commandModels . Any ( ) ? HelperExtensions . GetIntegrationCommandQueue ( commandModels . First ( ) ) :
74+ throw new InvalidOperationException ( $ "Subscription could not be found for IntegrationEventHandler ['{ Model . Id } ', '{ Model . Name } ']") ;
75+
76+ attr . AddArgument ( $@ """{ queueName } """);
77+ attr.AddArgument(@" Connection = "" QueueStorage: DefaultEndpoint""") ;
78+ } ) ;
79+ } ) ;
80+ method . AddParameter ( UseType ( "System.Threading.CancellationToken" ) , "cancellationToken" ) ;
81+
82+ method . AddTryBlock ( block =>
83+ {
84+ var dispatch = new CSharpAwaitExpression ( new CSharpInvocationStatement ( "_dispatcher" , "DispatchAsync" )
85+ . AddArgument ( "_serviceProvider" )
86+ . AddArgument ( "message" )
87+ . AddArgument ( "_serializerOptions" )
88+ . AddArgument ( "cancellationToken" ) ) ;
89+ dispatch . AddMetadata ( "service-dispatch-statement" , true ) ;
90+
91+ block . ApplyUnitOfWorkImplementations ( this , @class . Constructors . First ( ) , dispatch ) ;
92+
93+ block . AddStatement ( $@ "await _eventBus.FlushAllAsync(cancellationToken);") ;
94+ } ) ;
95+ method . AddCatchBlock ( UseType ( "System.Exception" ) , "ex" , block =>
3596 {
36- param . IntroduceReadonlyField ( ) ;
97+ block . AddStatement ( $@ "_logger.LogError(ex, ""Error processing { @class . Name } "");") ;
98+ block . AddStatement ( "throw;" ) ;
3799 } ) ;
38100 } ) ;
39101 } ) ;
40102 }
41103
104+ public override void AfterTemplateRegistration ( )
105+ {
106+ if ( ExecutionContext . Settings . GetAzureQueueStorageSettings ( ) . MessageEncoding ( ) . AsEnum ( ) == AzureQueueStorageSettings . MessageEncodingOptionsEnum . None )
107+ {
108+ ExecutionContext . EventDispatcher . Publish ( new HostSettingRegistrationRequest ( "extensions" , new
109+ {
110+ queues = new
111+ {
112+ messageEncoding = "none"
113+ }
114+ } ) ) ;
115+ }
116+ }
117+ //
118+
42119 private string GetFunctionName ( )
43120 {
44121 var functionName = $ "{ Model . Name . RemoveSuffix ( "Handler" ) } Consumer";
0 commit comments