Das ist eine für den Ausdruck optimierte Ansicht des gesamten Kapitels inkl. Unterseiten. Druckvorgang starten.

Zur Standardansicht zurückkehren.

Überblick

Was die dsyr.DataBridge ist, wie sie funktioniert und wie sie technisch aufgebaut ist.

Dieses Kapitel erklärt die dsyr.DataBridge auf zwei Ebenen: konzeptuell für alle, die verstehen wollen wie die Synchronisation abläuft — und technisch für diejenigen, die den genauen Aufbau der Komponenten kennen möchten.

SeiteZielgruppeInhalt
Wie es funktioniertAlle NutzerDatenfluss in einfachen Schritten
ArchitekturTechniker, AdministratorenAzure-Komponenten, Services, Queues

1 - Wie es funktioniert

Der Datenfluss der dsyr.DataBridge in fünf Schritten — verständlich erklärt ohne technischen Ballast.

Das Grundprinzip

Die dsyr.DataBridge arbeitet wie ein kontinuierlicher Datenstrom zwischen zwei Systemen. Sie fragt regelmäßig: „Was hat sich seit dem letzten Mal geändert?" — und überträgt genau diese Änderungen ins Zielsystem. Nichts mehr, nichts weniger.

Kein manueller Export. Kein Doppelpflegen. Keine Vollsynchronisation, die alles neu schreibt. Nur die Differenz, automatisch, im Minutentakt.


Der Datenfluss in fünf Schritten

flowchart LR
    A([Quelldaten<br/>ändern sich]) -->|"alle 15 Sekunden<br/>prüfen"| B[DataBridge<br/>erkennt Änderung]
    B -->|"Datensätze<br/>puffern"| C[(Service Bus<br/>Queue)]
    C -->|"Nachricht<br/>verarbeiten"| D[Felder<br/>mappen & wandeln]
    D -->|"schreiben"| E([Zielsystem<br/>aktualisiert])
    E -->|"Stand merken"| F[(Watermark<br/>gespeichert)]
    F -.->|"nächster Lauf<br/>startet hier"| B

    style A fill:#e8f5f1,stroke:#18b28d,color:#111111
    style E fill:#e8f5f1,stroke:#18b28d,color:#111111
    style C fill:#fff3e0,stroke:#f57c00,color:#111111
    style F fill:#e3f2fd,stroke:#1565c0,color:#111111

Schritt 1 — Änderungen erkennen

Alle 15 Sekunden (konfigurierbar über GetChangesTimerExpression) startet ein Timer. Die DataBridge fragt das Quellsystem: „Gib mir alle Datensätze, die seit meinem letzten Stand geändert wurden."

Dafür nutzt sie den gespeicherten Watermark — einen Zeitstempel oder einen Änderungstoken, der beim letzten erfolgreichen Lauf hinterlegt wurde.

Schritt 2 — Änderungen puffern

Gefundene Datensätze landen nicht sofort im Zielsystem, sondern zunächst in einer Azure Service Bus Queue. Das entkoppelt Erkennung und Verarbeitung: Selbst wenn das Zielsystem kurz nicht erreichbar ist, gehen keine Daten verloren. Die Queue speichert die Nachrichten bis zur erfolgreichen Verarbeitung.

Schritt 3 — Felder mappen und wandeln

Jede Nachricht aus der Queue wird einzeln verarbeitet. Die DataBridge liest die konfigurierten Mappings und weiß: Quellfeld A geht in Zielfeld B, Wert X wird zu Wert Y übersetzt, ein fehlendes Feld bekommt einen Standardwert.

Dieser Schritt ist vollständig konfigurierbar — ohne Programmierung.

Schritt 4 — Ins Zielsystem schreiben

Der gemappte Datensatz wird ins Zielsystem geschrieben. Die DataBridge prüft dabei anhand eines konfigurierten Schlüssels, ob der Datensatz dort bereits existiert:

  • Existiert: Update des vorhandenen Datensatzes
  • Existiert nicht: Neuanlage

Schritt 5 — Watermark aktualisieren

Nach erfolgreichem Durchlauf speichert die DataBridge den neuen Stand als Watermark. Beim nächsten Timer-Aufruf dient dieser Wert als Startpunkt — so werden Datensätze weder doppelt übertragen noch übersprungen.


Bidirektionale Synchronisation

Die fünf Schritte gelten für eine Richtung der Synchronisation. Wenn Daten in beide Richtungen fließen sollen (z. B. BC → Dataverse und Dataverse → BC), werden zwei unabhängige Jobs konfiguriert — jeder mit eigenem Quell- und Zielsystem, eigenem Mapping und eigenem Watermark.


Prioritäten und Parallelverarbeitung

Nicht alle Datensätze sind gleich wichtig. Die DataBridge kennt drei Prioritätsstufen:

PrioritätTypischer Einsatz
HochZeitkritische Stammdaten (z. B. Preise, Kundendaten)
StandardNormale Synchronisation (Bestellungen, Kontakte)
NiedrigHistorische Daten, große Datenmengen ohne Zeitdruck

Nachrichten mit hoher Priorität werden bevorzugt verarbeitet, ohne dass niedrigere Prioritäten blockiert werden.


Was passiert bei Fehlern?

Schlägt die Verarbeitung einer Nachricht fehl, gibt es mehrere Sicherheitsnetze:

  1. Automatischer Wiederholungsversuch — die Nachricht wird nach kurzer Wartezeit erneut verarbeitet (bis zu einer konfigurierten Maximalanzahl).
  2. Transitive Queue — meldet das Zielsystem einen Konflikt (z. B. ein Duplikat), wird die Nachricht in eine separate Queue abgelegt, damit sie den Hauptpfad nicht blockiert. Dort wird sie nicht automatisch erneut verarbeitet, sondern bei Bedarf manuell zurückgestellt.
  3. Dead-Letter Queue — dauerhaft nicht verarbeitbare Nachrichten werden dort gesammelt und können analysiert oder manuell re-queued werden.

In keinem dieser Fälle gehen Daten still verloren. Das Monitoring und die konfigurierbaren Alerts informieren aktiv, wenn die Dead-Letter Queue Einträge enthält.

2 - Technische Architektur

C4-Modell (Context, Container, Component), Azure-Komponenten, Service-Schichten, Queue-Struktur und Connector-Hierarchie der dsyr.DataBridge.

Azure-Komponenten

Die DataBridge besteht aus mehreren Azure-Diensten, die in einer gemeinsamen Ressourcengruppe betrieben werden:

KomponenteDienstRolle
Function AppAzure Functions (Isolated Worker, .NET 10)Ausführungsumgebung für alle Funktionen
App Service PlanMicrosoft.Web/serverfarmsCompute-Plan: Y1 (Consumption, Standard) oder EP1–EP3 (Premium)
Service BusAzure Service Bus NamespacePuffer zwischen Erkennung und Verarbeitung
Table StorageAzure Storage AccountLaufzeit-Konfiguration (Connections, Jobs, Mappings, Watermark)
Application InsightsAzure MonitorLogging, Telemetrie, Alerting; Traces und ausgehende Aufrufe werden gesampelt
Grafana-DashboardMicrosoft.Dashboard/dashboardsVorkonfiguriertes Betriebsdashboard im Application-Insights-Blade (seit v2.1, wird immer mitdeployt)
Metric Alerts + Action GroupAzure MonitorDead-Letter- und Queue-Längen-Alerts, optional über enableAlerts

Architektur nach dem C4-Modell

Die folgenden drei Diagramme folgen dem C4-Modell (Context → Container → Component) — von außen nach innen, jede Ebene zoomt weiter in die DataBridge hinein.

Ebene 1 — System Context

Wer nutzt die DataBridge, und mit welchen Systemen tauscht sie Daten aus?

flowchart TB
    admin(["👤 Administrator"])
    ki(["🤖 KI-Assistent<br/><small>z. B. Claude Code</small>"])

    databridge["dsyr.DataBridge<br/><small>Synchronisiert Datensätze zwischen<br/>Quell- und Zielsystemen</small>"]

    bc["D365 Business Central<br/><small>ERP — Quelle/Ziel</small>"]
    ce["D365 CE / Dataverse<br/><small>CRM — Quelle/Ziel</small>"]
    nav["D365 NAV<br/><small>ERP — Quelle/Ziel</small>"]
    sql[("SQL-Datenbanken<br/><small>nur Quelle</small>")]
    rest["Beliebige REST-API<br/><small>über OpenAPI-Spec</small>"]

    admin -->|"konfiguriert, überwacht"| databridge
    ki -->|"MCP über HTTPS"| databridge
    databridge <-->|"OData v4, OAuth2/API-Key"| bc
    databridge <-->|"Dataverse SDK"| ce
    databridge <-->|"OData, Basic Auth"| nav
    databridge -->|"ADO.NET"| sql
    databridge <-->|"REST, aus Spec aufgelöst"| rest

    style databridge fill:#1565c0,color:#fff,stroke:#0d47a1,stroke-width:2
    style admin fill:#08427b,color:#fff,stroke:#052e56
    style ki fill:#08427b,color:#fff,stroke:#052e56
    style bc fill:#8b8b8b,color:#fff,stroke:#666
    style ce fill:#8b8b8b,color:#fff,stroke:#666
    style nav fill:#8b8b8b,color:#fff,stroke:#666
    style sql fill:#8b8b8b,color:#fff,stroke:#666
    style rest fill:#8b8b8b,color:#fff,stroke:#666

Ebene 2 — Container

Innerhalb des eigenen Azure-Abonnements des Kunden besteht die DataBridge aus fünf Containern (im C4-Sinn: separat betreibbare/skalierbare Einheiten):

flowchart TB
    admin(["👤 Administrator"])
    ki(["🤖 KI-Assistent"])

    subgraph RG["Ressourcengruppe des Kunden"]
        func["Function App<br/><small>.NET 10, Isolated Worker</small>"]
        sb[["Service Bus<br/><small>7 Queues</small>"]]
        ts[("Table Storage<br/><small>connections/jobs/<br/>mappings/watermark</small>")]
        appins["Application Insights"]
        graf["Grafana-Dashboard"]

        func <-->|"Nachrichten"| sb
        func <-->|"Konfiguration & Watermark"| ts
        func -->|"Telemetrie"| appins
        appins --> graf
    end

    systems["Quell-/Zielsysteme<br/><small>D365 BC/CE/NAV, SQL, REST</small>"]

    admin -->|"konfiguriert (Table Storage)"| func
    ki -->|"ruft MCP-Tools auf"| func
    func <-->|"liest/schreibt Datensätze"| systems

    style func fill:#1565c0,color:#fff,stroke:#0d47a1,stroke-width:2
    style sb fill:#1565c0,color:#fff,stroke:#0d47a1
    style ts fill:#1565c0,color:#fff,stroke:#0d47a1
    style appins fill:#1565c0,color:#fff,stroke:#0d47a1
    style graf fill:#1565c0,color:#fff,stroke:#0d47a1
    style admin fill:#08427b,color:#fff,stroke:#052e56
    style ki fill:#08427b,color:#fff,stroke:#052e56
    style systems fill:#8b8b8b,color:#fff,stroke:#666
    style RG fill:#f5f5f5,stroke:#999,color:#111111,stroke-dasharray: 4 2

Ebene 3 — Component

Innerhalb des Containers Function App sind die Funktionen (Trigger-Ebene) von der Service-Schicht (Logik-Ebene) getrennt. Um das Diagramm lesbar zu halten, wird die Service-Schicht hier als ein Component dargestellt und direkt im Anschluss (Abschnitt Service-Schicht) sowie in der Connector-Hierarchie weiter aufgeschlüsselt — das C4-Modell ist für genau dieses schrittweise Hineinzoomen gedacht.

flowchart TB
    subgraph FA["Function App"]
        getchanges["GetChanges<br/><small>Timer</small>"]
        processq["Process*QueueItems<br/><small>Service-Bus-Trigger (3x)</small>"]
        executejob["ExecuteJob / ExecuteHttpRequest<br/><small>HTTP</small>"]
        diagapi["CheckList / Validate / JobApi /<br/>MappingApi<br/><small>HTTP, read-only</small>"]
        mcp["McpApi<br/><small>MCP-Server für KI-Assistenten</small>"]
        orch["Orchestrator<br/><small>Durable, alternativ zu GetChanges</small>"]

        services["Service-Schicht<br/><small>InitializationService + 8 Services<br/>— siehe Detail-Diagramm unten</small>"]
        connectors["Connector-Schicht<br/><small>IConnector-Implementierungen<br/>— siehe Connector-Hierarchie</small>"]

        getchanges --> services
        processq --> services
        executejob --> services
        diagapi --> services
        mcp --> services
        orch --> services
        services --> connectors
    end

    style services fill:#1565c0,color:#fff,stroke:#0d47a1,stroke-width:2
    style connectors fill:#1565c0,color:#fff,stroke:#0d47a1,stroke-width:2
    style FA fill:#f5f5f5,stroke:#999,color:#111111,stroke-dasharray: 4 2

Die Azure Functions

Alle Funktionen laufen in derselben Function App und teilen sich eine gemeinsame Service-Schicht:

FunktionTriggerAufgabe
GetChangesTimer (konfigurierbar über GetChangesTimerExpression)Fragt alle fälligen Quellsysteme nach Änderungen und schreibt Nachrichten in die Service Bus Queues
ProcessStandardQueueItemsService Bus sbqexportVerarbeitet Nachrichten mit Standard-Priorität
ProcessHighPriorityQueueItemsService Bus sbqhighexportVerarbeitet Nachrichten mit hoher Priorität
ProcessLowPriorityQueueItemsService Bus sbqlowexportVerarbeitet Nachrichten mit niedriger Priorität
ExecuteJobHTTP POSTFührt einen einzelnen Job manuell und sofort aus
ExecuteHttpRequestHTTP POSTDiagnose: führt eine ad-hoc HTTP-GET-Anfrage gegen eine beliebige URL aus, unabhängig von den konfigurierten Connectoren
GetInfoHTTP GETGibt die Versionsnummer der Function App zurück
CheckListHTTP GETDiagnose: prüft Mappings gegen die Attribute der beteiligten Systeme
ValidateHTTP GETDiagnose: validiert die hinterlegte Konfiguration
JobApi (GET /job, GET /job/{rowKey})HTTP GETDiagnose: gibt die eingelesene jobs-Konfiguration (alle bzw. ein einzelner Job) zurück
MappingApi (GET /mapping, GET /mapping/{name})HTTP GETDiagnose: gibt die eingelesene mappings-Konfiguration (alle bzw. ein einzelnes Mapping anhand seines Namens) zurück
McpApi (POST /mcp)HTTP POSTRead-only MCP-Server für KI-Assistenten — bündelt Jobs/Mappings/Queues/Connector-Metadaten als Tools

Zusätzlich existiert eine optionale Durable-Orchestrierung als Alternative zum Timer-Pfad (StartGetChangesOrchestration, GetChangesOrchestrator, GetChangesActivity und die Durable Entity JobState). Sie wird ausschließlich per HTTP gestartet und ist im Regelbetrieb nicht aktiv.

Alle Funktionen lassen sich einzeln per App-Setting deaktivieren (AzureWebJobs.<Funktionsname>.Disabled), ohne die Function App neu zu deployen.


Queue-Struktur im Service Bus

Der Service Bus Namespace enthält sieben Queues:

flowchart TD
    GC[GetChanges] -->|Priorität: Hoch| QH[sbqhighexport]
    GC -->|Priorität: Standard| QS[sbqexport]
    GC -->|Priorität: Niedrig| QL[sbqlowexport]

    QH --> PH[ProcessHighPriorityQueueItems]
    QS --> PS[ProcessStandardQueueItems]
    QL --> PL[ProcessLowPriorityQueueItems]

    PH -->|"Konflikt im Ziel<br/>(HTTP 409)"| TH[sbqtransitivehigh]
    PS -->|"Konflikt im Ziel<br/>(HTTP 409)"| TS[sbqtransitivestandart]
    PL -->|"Konflikt im Ziel<br/>(HTTP 409)"| TL[sbqtransitivelow]

    PH -->|"SkipOutdatedMessages"| IGN[sbqignored]
    PS --> IGN
    PL --> IGN

    PH -->|"max. Zustellversuche<br/>überschritten"| DLQ[("Dead-Letter-Subqueue<br/>je Queue")]
    PS --> DLQ
    PL --> DLQ

    style QH fill:#fce4ec,stroke:#c62828,color:#111111
    style QS fill:#fff3e0,stroke:#e65100,color:#111111
    style QL fill:#e8f5e9,stroke:#2e7d32,color:#111111
    style TH fill:#fce4ec,stroke:#c62828,color:#111111,stroke-dasharray: 4 2
    style TS fill:#fff3e0,stroke:#e65100,color:#111111,stroke-dasharray: 4 2
    style TL fill:#e8f5e9,stroke:#2e7d32,color:#111111,stroke-dasharray: 4 2
    style IGN fill:#f3e5f5,stroke:#6a1b9a,color:#111111
    style DLQ fill:#b0bec5,stroke:#37474f,color:#111111
QueueZweck
sbqhighexport / sbqexport / sbqlowexportPrimäre Verarbeitungs-Queues nach Priorität
sbqtransitivehigh / sbqtransitivestandart / sbqtransitivelowZiel-Queues bei Konflikten im Zielsystem (HTTP 409 / Duplikat-Datensatz), damit die Nachricht den Hauptpfad nicht blockiert
sbqignoredVeraltete Nachrichten (Quelldatum < Zieldatum bei aktivem SkipOutdatedMessages)
Dead-Letter-SubqueueJede Queue besitzt eine eigene Dead-Letter-Subqueue (<queuename>/$deadletterqueue) für Nachrichten, die nach maxDeliveryCount Versuchen nicht verarbeitet werden konnten

Service-Schicht

Alle Funktionen teilen eine gemeinsame Service-Schicht. Die Services selbst sind DI-Singletons; lazy und thread-sicher nachgeladen wird die Konfiguration beim ersten Aufruf. Das folgende Diagramm zoomt gegenüber dem C4-Component-Diagramm oben gezielt auf den InitializationService-Teilbaum und dessen Initialisierungsreihenfolge. InitializationService (bis v2.3 CoreService) ist reduziert auf Initialisierung und Ready/Error-Zustand — er ist kein Service-Locator: ProcessJobsForRetrievalInOrderService und ProcessQueueMessageService werden von den Functions, die sie brauchen (GetChanges/ExecuteJob bzw. Process*QueueItems), direkt injiziert, nicht über ihn geroutet:

flowchart TB
    IS["InitializationService<br/>Lazy Konfigurations-Laden<br/>thread-sicher"]

    IS --> STORE["StorageService<br/>Table-Storage-CRUD"]
    IS --> CONS["ConnectionService<br/>Verwaltet Connector-Instanzen<br/>je Connection-Name"]
    IS --> MS["MappingService<br/>Gruppiert FieldMappings<br/>je Mapping-Name"]
    IS --> JS["JobService<br/>Prüft Schedules<br/>validiert Job-Konfiguration"]
    IS --> CHK["CheckListService<br/>Diagnose"]

    PJRS["ProcessJobsForRetrievalInOrderService<br/>Erkennungs-Pfad"] --> WS["WatermarkService"]
    PJRS --> SBS["ServiceBusService"]
    PQS["ProcessQueueMessageService<br/>Verarbeitet einzelne<br/>Nachrichten End-to-End"] --> SBS
    PQS --> WS
    JS --> WS
    WS --> STORE

    style IS fill:#e8f5f1,stroke:#18b28d,color:#111111,stroke-width:2

Daneben stehen Querschnitts-Services, die nicht unter dem InitializationService-Teilbaum hängen:

  • SettingsService — liest App-Settings und Connection-Strings aus der Konfiguration (nicht aus Table Storage)
  • MetricsService — sendet vorab aggregierte Custom Metrics an Application Insights (z. B. ChangesDetected je Job)
  • McpToolService — bündelt die Tool-Logik hinter dem MCP-Server: ruft JobService, MappingService, ServiceBusService und ConnectionService auf und stößt darüber (wie JobApi/MappingApi) selbst einmalig InitializationService.EnsureInitializedAsync an — hängt also nicht im InitializationService-Baum, sondern davor

Initialisierungsreihenfolge:

  1. StorageService prüft die vier Tabellen und legt fehlende an
  2. ConnectionService liest connections, deserialisiert die JSON-Verbindungsdaten und führt je System einen Verbindungstest aus
  3. MappingService liest mappings und gruppiert die Einträge nach Mapping-Name
  4. JobService liest jobs und validiert sie: existieren Verbindungen und Mappings? Ist die Cron-Expression gültig?

Schlägt ein Verbindungstest fehl, wird der Fehler protokolliert und der laufende Aufruf mit einer Exception beendet. Die Initialisierung wird zurückgesetzt und beim nächsten Timer-Aufruf bzw. bei der nächsten Queue-Nachricht erneut versucht (Self-Repair). Bei Queue-Nachrichten bedeutet das: die Nachricht wird abandoned und zählt gegen maxDeliveryCount.


Connector-Hierarchie

Detailansicht der Komponente Connector-Schicht aus dem C4-Component-Diagramm oben — als UML-artiges Klassendiagramm, da C4 Vererbungshierarchien nicht sauber abbilden kann. Jedes Quell- und Zielsystem wird durch einen Konnektor abstrahiert. Alle Konnektoren implementieren dasselbe Interface und sind damit gegeneinander austauschbar:

flowchart TD
    IC["«interface»<br/>IConnector"]

    CB["ConnectorBase<br/>Serialisierung, Caching,<br/>Filter-Templating,<br/>Key-Vault-Integration"]

    HCB["HttpConnectorBase<br/>OAuth2 / Basic Auth,<br/>Token-Lifecycle,<br/>HTTP-Client-Management"]

    SCB["SqlConnectorBase<br/>ADO.NET, Schema-Caching,<br/>Paging (OFFSET / FETCH)"]

    IC --> CB
    CB --> HCB
    CB --> SCB
    CB --> CE["CeConnector<br/>Dataverse SDK"]

    HCB --> BC["BcConnector<br/>OData v4 API"]
    HCB --> NAV["NavConnector<br/>OData / Basic Auth"]
    HCB --> OA["OpenApiConnector<br/>Generische REST-API,<br/>Pfade aus OpenAPI-Spec"]

    SCB --> SQL[MsSqlConnector]
    SCB --> PG[PostgreSqlConnector]
    SCB --> MY[MySqlConnector]
    SCB --> OR[OracleConnector]

    style IC fill:#e3f2fd,stroke:#1565c0,color:#111111
    style CB fill:#e8f5f1,stroke:#18b28d,color:#111111
    style HCB fill:#fff3e0,stroke:#e65100,color:#111111
    style SCB fill:#fce4ec,stroke:#c62828,color:#111111

Für die Typumwandlung greifen zwei Bausteine ineinander:

  • TargetValueMapper — wählt anhand des Zielsystem-Metadatentyps (EDM bei BC/NAV, AttributeMetadata bei Dataverse) den passenden Resolver aus. Existiert je Connector.
  • AttributeResolver — führt die eigentliche Typumwandlung durch (Boolean, Date, DateTime, Decimal, Guid, Integer, String; bei Dataverse zusätzlich Picklist, Lookup, Money, State/Status, MultiSelect). Liegt als Resolver-Familie je Systemtyp vor.

IConnector stellt zusätzlich GetTableMetadata(tableName, apiPath) bereit: liefert Typ, Nullable, maximale Länge und Primary-Key-Information je Spalte direkt aus dem Zielsystem — implementiert für alle Connector-Typen, seit v2.3 auch für die SQL-Familie. Dient vor allem dem MCP-Server zur Validierung von Mappings gegen das echte Schema.


Änderungserkennung pro Connector-Typ

Die Methode, mit der Änderungen erkannt werden, unterscheidet sich je nach System:

ConnectorMechanismusWatermark-Typ
D365BCOData-$filter auf das im Job konfigurierte Feld WatermarkField (z. B. lastModifiedDateTime)datetime
D365CE / DataverseDataverse Change Tracking API (opaker Token)string
D365NAVOData-$filter auf das konfigurierte WatermarkFielddatetime oder date
SQL-DatenbankenSQL-WHERE-Klausel auf das konfigurierte WatermarkFielddate oder datetime
OpenAPIWatermarkField wird als JSON-Pfad auf jeden gelesenen Datensatz angewendet; Filter wird unverändert als Query-String an die API angehängt (API-abhängig)datetime

Der Watermark-Wert wird pro Job in der Tabelle watermark gespeichert und am Ende der Erkennungsphase fortgeschrieben. Ein manuelles Leeren des Watermarks erzwingt einen vollständigen Neulauf des jeweiligen Jobs.


Über CRUD hinaus: Aktions-Jobs, job-eigene Pfade, eingebettete Kinder

Drei neuere Erweiterungen des Job-/Mapping-Modells betreffen nicht nur den OpenAPI-Konnektor, sind dort aber am relevantesten:

  • InvokeAction — ein Job mit einem Action-Wert, der keinem bekannten JobActionType entspricht, ruft statt eines CRUD-Vorgangs einen benannten, nicht-CRUD-Endpunkt auf (z. B. einen OpenAPI-operationId oder ein CE-OrganizationRequest). Details: Jobs → InvokeAction.
  • Job-eigene Source-/Target-Pfade — ein Job kann über Source/Target die SourceTable/TargetTable seiner Mapping-Zeilen überschreiben (bzw. bei fehlendem Mapping ein synthetisches Mapping erzeugen), sodass eine Mapping-Gruppe für mehrere Ressourcen oder Aktionspfade wiederverwendet werden kann. Details: Jobs → Source und Target.
  • EmbedChildren — bettet die Datensätze eines referenzierten Kind-Jobs bereits beim Lesen in die Nachricht des Elterndatensatzes ein, sodass Eltern- und Kind-Datensätze gemeinsam als eine Nachricht verarbeitet werden (derzeit nur mit D365CE als Quellsystem). Details: Mappings → EmbedChildren.

Retry- und Fehlerverhalten

SzenarioVerhalten
Konflikt im Zielsystem (HTTP 409 / Duplikat)Weiterleitung in die passende Transitive-Queue
Transientes Netzwerkproblem, Zielsystem temporär nicht erreichbarBackoff (DeliveryCount² · 1000 ms), Abandon, erneute Zustellung nach Lock-Ablauf
Veraltete Nachricht (Quelle älter als Ziel)Bei aktivem SkipOutdatedMessages: Weiterleitung in sbqignored
Maximale Zustellversuche überschrittenWeiterleitung in die Dead-Letter-Subqueue der jeweiligen Queue, Alert ausgelöst (wenn konfiguriert)
Initialisierungsfehler (Verbindung)Fehler wird geloggt, laufender Aufruf bricht ab, nächster Aufruf versucht erneut