Wie bereits im quiTeq Artikel vom 24. Februar 2022 beschrieben, können mittels Extensions gewisse Limitationen der Azure Services erfolgreich umgangen werden.
Herausforderungen
- Datei-Handling: Eine Logic App (Consumption/Standard) kann solch grosse XML-Dateien nicht laden, um sie per XSLT oder per Liquid Template zu transformieren. Der Blob Storage Connector hat ein Limit von 1 GB.
- Laufzeit: Logic Apps (Consumption/Standard) haben eine systembedingt beschränkte Laufzeit. Sie werden nach Überschreitung des Timeouts automatisch beendet.
- Kosten: Der Kunde verlangt verständlicherweise nach einer kostengünstigen Lösung, sodass nicht alle in Azure zur Verfügung stehenden Ressourcen in Betracht gezogen werden können.
Lösungsansätze
- Azure Functions: Mit diesem Ansatz umgehen wir Problem Nr. 1. In Azure Functions können wir den kompletten Werkzeugkasten des .NET Frameworks zum Einsatz bringen. Also wäre das Handling grosser Dateien kein sonderliches Problem. Allerdings stossen wir hier immer noch an Limits: dauert der Prozess innerhalb der Function länger als der Logic App Timeout haben wir mit Problem Nr. 2 zu kämpfen.
- Azure Data Factory: Scheint eine gute Lösung für solche ‚Big Data‘ Szenarios zu sein. In unserem Fall leider nein: mit den Bordmitteln können wir zwar XML als Inputformat verwenden, allerdings ist das Outputformat auf einige wenige Formate beschränkt (standardmässig kein XML). Für die Transformation tief strukturierter XML Objekte ist der Standardmapper auch nur bedingt geeignet.
- Azure Durable Functions: Hierbei handelt es sich um Extensions zu Azure Functions. Es gibt verschieden Typen dieser Functions (die Begriffe in den Klammern sind meine eigenen Umschreibungen, um das Handling etwas zu vereinfachen):
- Trigger Function (Starter)
- Orchestration Function (Orchestrator)
- Activity Function (Processor | Caller)
Den dritten Lösungsansatz, die Azure Durable Functions, verwenden wir zur Umsetzung unserer Problemstellung.
Um eine solche Lösung zu realisieren, benötigt man eine Azure Subscription, eine Function App und einen App-Service-Plan, in dem die Function App gehostet wird. Ich werde das reale Szenario etwas vereinfachen. Wie oben beschrieben, soll ein grosses XML File mit Produktdaten in drei verschiedene Zielformate (JSON, XML, CSV) transformiert werden.
Für unsere Solution benötigen wir einen Starter (Typ: Trigger Function), der den öffentlichen https-Endpunkt bereitstellt. Er kann mit notwendigen Parametern aufgerufen werden, um den Prozessfluss innerhalb des Orchestrators zu steuern. Für die Callback-Funktionalität kann im Body eine URL mitgegeben werden, an die nach Beendigung aller Prozesse das Ende gemeldet wird.
Wir benötigen weiter einen Orchestrator (Typ: Orchestration Function), der die Processoren entsprechend den Parametern startet.
Darüber hinaus benötigen wir für die beispielhaften drei Datentypen entsprechende Processoren (Typ: Activity Function), die die eigentliche (Transformations-) Arbeit machen.
Und einen Caller (Activity Function), der die bereitgestellte Callback-URL aufruft, um den Vollzug zu melden.
Hier ein Ablaufplan der ganzen Solution:
Funktionsweise
Allgemein wird die Starter-URL mit Steuerparametern und CallBack-URL über einen POST Request von einem Client aufgerufen.
Der Starter instanziiert dann den Orchestrator und übergibt die Steuerparameter und die CallBack-URL.
Der Orchestrator startet gemäss Steuerparameter den entsprechenden Processor und wartet, bis er seine Aufgabe erledigt hat. Danach ruft der Orchestrator den Caller auf und übergibt dabei die CallBack-URL.
Der Caller sendet einen Request an die CallBack-URL und signalisiert so dem Client, dass der Job beendet ist.
Den CallBack-Mechanismus kann man hervorragend in Azure Logic Apps einsetzen. Damit ist man in der Lage, die Logic App an der Stelle, an der der Starter aufgerufen wird, solange anzuhalten, bis der Caller die CallBack-URL aufruft. So kann man das Timeout, auch einer LA Consumption, ausser Kraft setzen. Der Aufruf des Starters erfolgt über eine ‘http Webhook’ Action.
Das sieht dann in etwa so aus:
Die Logic App bleibt an genau dieser Stelle stehen (und das können Stunden oder Tage sein) bis der Caller die übergebene URL aufruft. Danach setzt die Logic App ihren Run fort und kann dann den Transport der transformierten Daten anstossen.
Fazit
Dank dieser Umsetzung konnten die Limitierungen der Azure Integration Services umgangen werden. Eine Solution zum Testen hat man sich schnell zusammen ‘gesniped’. Man kann sie lokal ausführen und debuggen. Die Solution ist einfach erweiterbar, indem man neue Processor hinzufügt, die die neuen Aufgaben übernehmen.
Andreas Conrad, QUIBIQ Schweiz AG