==== Azure function ==== === Setting up IDE: Visual Studio Code === * Set up IDE https://learn.microsoft.com/de-de/azure/azure-functions/functions-develop-vs-code?tabs=node-v4%2Cpython-v2%2Cisolated-process&pivots=programming-language-python * Core Tools installieren https://learn.microsoft.com/de-de/azure/azure-functions/functions-run-local?tabs=windows%2Cisolated-process%2Cnode-v4%2Cpython-v2%2Chttp-trigger%2Ccontainer-apps&pivots=programming-language-python#install-the-azure-functions-core-tools Use to reload the env variables after installing $env:Path = ` [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + ` [System.Environment]::GetEnvironmentVariable("Path","User") Install packages locally, to make imports succeed pip install -r .\requirements.txt Make sure you select the right python version, for which you executed the "pip install" {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/7ygwRpbbkd.png}} {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/tzHBRiMKL5.png}} Then even under windows one can run "func start" to test linux functions func start {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/4HLTFBqBlR.png}} === Debugging Azure functions === == Validate Triggers== Often, if the "Azure Function" code has invalid imports, then the triggers are missing after the deployment. You can validate, **if the triggers were recognized successfully**, by starting the Azure Function locally. The recognized triggers will be listed as following: {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/4HLTFBqBlR.png}} == Validate Files == Often the files of Azure Function - are not deployed or lost after the terraform-update. Check if the files are available and up to date. Maybe teh reason why the trigger isnt there - is because you have not deplyoed the app? {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/41O4sn3oKW.png}} == Test execute and see output == You can execute the Azure functions from the portal. And you can validate the behavior via "Portal > Azure Function > Log Stream" {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/MbDC47HSC7.png}} == Validate Imports == Just do, to see if the imports are understood correctly: pip install -r .\requirements.txt {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/7ygwRpbbkd.png}} === Azure functions in Azure Portal === The runtime {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/Hgmm9qaqwh.png}} The trigger and code. Only available after uploading the code into the function, via ''az functionapp deployment source config-zip -g $resourceg -n $functionname --src app.zip'' which uploads the ''app.zip'' into the associated blob-container, from where it automatically is executed by the azure_function. {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/y8RhZMDYCe.png}} {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/8TPkU8gbcT.png}} Here the function ''http_trigger'' was recognized. {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/KAkOMqgCRq.png}} The Function URL {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/bYSSoOXd9R.png}} The URL response {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/TRJIKVCUQ4.png}} === Limitations of Azure functions === * Azure functions - are NOT only serverless. * You can choose a premium subscription and deploy your **Azure function** as an always running instance into your network * You CAN'T use a serverless function - in a private network * You **CAN'T have multiple triggers** for a function. ONly one of * http_trigger * Blob trigger * CosmosDB trigger * EventHub trigger * Queue trigger * ServiceBus Queue trigger * ServiceBus Topic trigger * Timer Trigger === Serverless Azure functions === https://learn.microsoft.com/en-us/azure/azure-functions/functions-proxies === Python linux functions === https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-python?tabs=linux%2Cbash%2Cazure-cli%2Cbrowser Run like https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-python?tabs=linux%2Cbash%2Cazure-cli%2Cbrowser#run-the-function-locally func start IN general read about developing locally: https://learn.microsoft.com/en-us/azure/azure-functions/functions-develop-local === Azure Service Bus Pub/Sub === Publishing function import logging import azure.functions as func app = func.FunctionApp() # vs output into queue for python # https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus-output?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cextensionv5&pivots=programming-language-python @app.route(route="http_trigger_queue", auth_level=func.AuthLevel.ANONYMOUS) @app.service_bus_queue_output(arg_name="message", connection="ServiceBusConnection", queue_name="alfdevapi5servicebusqueue") def http_trigger_queue(req: func.HttpRequest, message: func.Out[str]) -> func.HttpResponse: logging.info('Python HTTP trigger function processed a request.') logging.info('Python HTTP trigger function processed a request.') myMessage = "Hi alf this is my message via the queue to you." logging.info(myMessage) input_msg = req.params.get('message') message.set(f"{myMessage} {input_msg}") return func.HttpResponse( "This function should process queue messages.", status_code=200 ) Subscribing function import logging import azure.functions as func app = func.FunctionApp() @app.service_bus_queue_trigger(arg_name="azservicebus", queue_name="alfdevapi5servicebusqueue", connection="ServiceBusConnection") def servicebus_trigger(azservicebus: func.ServiceBusMessage): logging.warn('Python ServiceBus Queue trigger processed a message: %s', azservicebus.get_body().decode('utf-8')) Here you can see, that when the publishing function is executed, via Test Then the consuming function is receiving the message from the queue. {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/MbDC47HSC7.png}} === Azure Functions Java === https://stackoverflow.com/questions/77360325/cannot-create-java-function-in-azure-function-app mvn clean install mvn azure-functions:run mvn azure-functions:deploy Java SDK content * https://azure.github.io/azure-sdk-for-java/servicebus.html * https://learn.microsoft.com/en-us/java/api/com.azure.messaging.servicebus.servicebusclientbuilder?view=azure-java-stable * === Azure Service Topic Pub with session === requirements.txt # DO NOT include azure-functions-worker in this file # The Python Worker is managed by Azure Functions platform # Manually managing azure-functions-worker may cause unexpected issues azure-functions datetime azure-servicebus local.settings.json { "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "", "FUNCTIONS_WORKER_RUNTIME": "python", "AzureWebJobsFeatureFlags": "EnableWorkerIndexing", "ServiceBusConnection": "Endpoint=sb://alfdevapi6sb.servicebus.windows.net/;SharedAccessKeyName=alfdevapi6servicebus_auth_rule;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=" } } Python V2 app, which uses the Python SDK, to send messages with SessionId * [[https://learn.microsoft.com/en-us/azure/developer/python/sdk/azure-sdk-overview?view=azure-python|Use the Azure libraries (SDK) for Python]] * [[https://learn.microsoft.com/en-us/python/api/azure-servicebus/azure.servicebus.servicebusclient?view=azure-python|ServiceBusClient Class]] import logging import azure.functions as func from datetime import datetime import json from azure.servicebus import ServiceBusClient, ServiceBusMessage import os app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS) # vs output into queue for python # https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus-output?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cextensionv5&pivots=programming-language-python TOPIC_NAME_A = "alfdevapi6topic" CONN_STRING = os.environ['ServiceBusConnection'] SESSION_ID = "008" @app.route(route="http_trigger") def http_trigger(req: func.HttpRequest) -> func.HttpResponse: logging.info('Python HTTP trigger function processed a request.') myMessage = "Hi alf this is my message via the queue to you." jsn_message_envelope = generateMessage(myMessage, SESSION_ID) logging.info(f"Will send envelope: {jsn_message_envelope}") servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONN_STRING) rith_sen = servicebus_client.get_topic_sender(TOPIC_NAME_A) rith_msg = ServiceBusMessage(jsn_message_envelope) rith_msg.session_id = SESSION_ID with rith_sen: rith_sen.send_messages(rith_msg) servicebus_client.close() return func.HttpResponse( "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.", status_code=200 ) def generateMessage(myMessage, mySessionId): now = datetime.now() print("now =", now) logging.info(f"Time stamp: {now}") dt_string = now.strftime("%d/%m/%Y %H:%M:%S") my_json_string = f""" {{ "body": "{myMessage}", "customProperties": {{ "timePublish": "{dt_string}", }}, "brokerProperties": {{ "SessionId": "{mySessionId}" }} }} """ return my_json_string == Publish a test message == Publishing a message {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/tVGGBpwi0d.png}} And see, which session was used during publishing, here ''session1'' {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/AegrzHZAfS.png}} == Consuming a test message == Now a consumer can consume the message {{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/at6eSPYnFS.png}}