Table of Contents

Azure function

Setting up IDE: Visual Studio Code

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”

Then even under windows one can run “func start” to test linux functions

func start

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:

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?

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”

Validate Imports

Just do, to see if the imports are understood correctly:

pip install -r .\requirements.txt

Azure functions in Azure Portal

The runtime

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.

Here the function http_trigger was recognized.

The Function URL

The URL response

Limitations of Azure functions

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.

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

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

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

And see, which session was used during publishing, here session1

Consuming a test message

Now a consumer can consume the message