==== 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}}