Some Azure functions or AWS Lambda Functions (other than the Http-triggered functions) may require parameters to be executed.
When the Azure or AWS runtime invokes a function (the function is triggered), it receives information related to the event that happened (e.g: the message that was received from a queue in a Queue Storage or a Service Bus function, or the blob that was stored in a Blob storage).
This information is needed inside the GeneXus Procedure object to program the logic of the function.
Therefore, in order to create a GeneXus Procedure that will be deployed as a function, you should consider some aspects regarding the parameters of the Procedure that are explained in this document.
- This is valid for functions whose trigger type is Blob, Service Bus, Queue, and Timer (all except HTTP)
- The GeneXus Procedures have to be main (Call protocol property = Internal).
1. First, import the external module called "GeneXusServerlessAPI." into the Knowledge Base. This module contains the definitions of the SDTs necessary to be passed as parameters to the function.
The Parm rule can be any of the following:
parm(in:&EventMessages,out:&EventMessageResponse);
parm(in:&RawData,out:&EventMessageResponse); // RawData is a char parameter
The header of EventMessage allows getting all the information of the event (such as its ID) from the Azure function or AWS Lambda.
The item EventMessageProperties is a property-value structure, where you can retrieve the body of the message, including its metadata. It's a dynamic structure to support any kind of message, regardless of the trigger type of the function.
Note: If you want to receive the message in a JSON string, use in:&RawData character parameter.
The EventMessageResponse has the following structure:
See Error Handling below for more details.
The following is an example of code where the EventMessage is processed.
for &EventMessage in &EventMessages.EventMessage
&MessageInfo = format(!"Id : %1, Source : %2, Version : %3, Date : %4, Data : %5"
,&EventMessage.EventMessageId
,&EventMessage.EventMessageSourceType
,&EventMessage.EventMessageVersion
,&EventMessage.EventMessageDate
,&EventMessage.EventMessageData)
//Process the message properties.
//This is a dynamic structure (property-value) which depends on the type of message and the provider.
for &EventMessageProperty in &EventMessage.EventMessageProperties
&Data += format(!"%1:%2 %3 ", &EventMessageProperty.PropertyId, &EventMessageProperty.PropertyValue, "-")
endfor
endfor
To deploy the Procedure as a function, use the deployment tool. See HowTo: Deploy as Azure Functions or HowTo: Deploy to AWS Lambda Function.
To avoid lost events, error handling is a very important issue to consider. This is for exceptions that require that the function is executed again until the maximum number of retries is reached.
By default, if any system error ocurrs, the function will retry.
In the GeneXus Procedure, if the application fails for any reason that can be controlled by the programmer, he can force the function to be re-run just by indicating HandleFailure property of &EventMessageResponse output variable to TRUE.
If &isError
&EventMessageResponse.HandleFailure = TRUE
&EventMessageResponse.ErrorMessage = "There was an error in the process."
Endif
Each type of function has its own management of retries and error handling in its infrastructure. According to the MS documentation, a retry policy can be defined for all functions in an app using the host.json file.
This file is added to the deployment package with basic settings. You have to modify it to your needs and include it as a file if you want.
In this case, the error is thrown to the Azure runtime, so the function can retry all the times it is configured to do so. In the case of Queue Storage or Service Bus, and if none of the retries is successful, the message is sent to a Poison queue or dead letter, respectively.
In this case, in the monitor of Azure Cloud, you will see the error as an Application Error:
HowTo: Monitor Azure Functions