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

Zur Standardansicht zurückkehren.

Debuggen

Die DataBridge lokal mit Breakpoints debuggen — entweder gegen die Podman-Testumgebung oder gegen eine echte Azure-Instanz.

Für Breakpoints und Step-Through läuft die DataBridge nicht im Container, sondern lokal als Prozess in der IDE. Zwei grundsätzlich verschiedene Varianten, je nachdem wogegen die lokal laufende DataBridge sprechen soll:

Gegen Podman debuggen

Azurite, Podman-Datenbanken, Service-Bus-Emulator, WireMock — alles lokal, keine Azure-Kosten, jederzeit zurücksetzbar.

→ Zum Artikel

Gegen echtes Azure debuggen

Echter Storage Account, echter Service Bus, echte Quell-/Zielsysteme — für Probleme aus einer konkreten Umgebung.

→ Zum Artikel

Gemeinsamkeiten

Beide Varianten teilen sich denselben Code und dieselbe launchSettings.json (Rider/Visual Studio/VS Code starten die DataBridge über dasselbe Projekt src/DataBridge/DataBridge.csproj auf Port 7062). Der Unterschied steckt ausschließlich in src/DataBridge/local.settings.json — welche Connection-Strings dort stehen, entscheidet, wogegen die DataBridge beim Start läuft. Die Datei ist nicht eingecheckt (.gitignore) und wird in beiden Varianten unterschiedlich befüllt:

  • Podman: generiert durch dev/up.sh --host aus der Vorlage dev/local.settings.dev.json.
  • Cloud: von Hand aus src/DataBridge/sample.local.settings.json kopiert und mit echten Werten gefüllt.

Beide Varianten steuern außerdem, ob GetChanges (Timer) und die Process*QueueItems-Funktionen laufen, über dieselben App-Settings (AzureWebJobs.<FunctionName>.Disabled) — nur der Weg dorthin unterscheidet sich (Toggle beim Start vs. Wert von Hand in local.settings.json). Details dazu in den beiden Artikeln.

1 - Gegen Podman debuggen

Die DataBridge lokal mit Breakpoints gegen die Podman-Testumgebung debuggen — konkret in Rider, Visual Studio und VS Code, inklusive Steuerung von GetChanges/Process*QueueItems und Einblick in den Service-Bus-Emulator.

Voraussetzung ist die Podman-Testumgebung. Der databridge-Container würde sonst Port 7062 belegen, deshalb startet up.sh/up.ps1 alles außer der DataBridge selbst:

dev\up.ps1 -HostMode mssql process
dev/up.sh --host mssql process

--host (bzw. -HostMode) lässt sich mit allen anderen Argumenten kombinieren (Datenbanken, Mocks, getchanges, process, servicebus) und startet alles außer dem databridge-Container selbst (dafür gibt es das Profil databridge, das sonst automatisch aktiv ist). Der Befehl generiert zusätzlich src/DataBridge/local.settings.json aus der Vorlage dev/local.settings.dev.json (Azurite über UseDevelopmentStorage=true, Service-Bus-Emulator über localhost statt über den Compose-Servicenamen servicebus, sowie die Toggles aus dev/.env, siehe GetChanges/Process*QueueItems steuern).

Damit die Connections in Azurite ebenfalls auf den Host statt auf die Compose-Servicenamen zeigen, setzt --host/-HostMode beim Seed-Container DATABRIDGE_RUNTIME=host (sonst container); seed.py ersetzt dann mssql/postgres/mysql/oracle/wiremock durch localhost mit dem passenden Host-Port aus dev/.env.

Zum Zurückwechseln auf den Container-Betrieb reicht ein Aufruf ohne --host/-HostMode — das generiert local.settings.json nicht neu, startet aber wieder den databridge-Container auf demselben Port. Die generierte Datei vorher löschen oder ignorieren, sie wird nicht mehr gelesen, solange kein lokaler Prozess läuft.

In der IDE starten

Alle drei IDEs nutzen dasselbe Projekt src/DataBridge/DataBridge.csproj und dasselbe Profil DataBridge aus src/DataBridge/Properties/launchSettings.json (startet mit --port 7062, passend zum MCP-Endpoint und zu curl-Aufrufen gegen localhost:7062).

Rider

  1. Lösung src/DataBridge.slnx öffnen (falls noch nicht offen).
  2. Oben rechts das Run-Profil DataBridge auswählen (Rider erkennt das Azure-Functions-Projekt automatisch und bietet das Profil aus launchSettings.json an).
  3. Auf das Käfer-Symbol (Debug) statt Play klicken, oder Shift+F9.
  4. Breakpoints wie gewohnt im Editor setzen (z. B. in ProcessQueueMessageService oder einem Connector).

Visual Studio

  1. src/DataBridge.slnx öffnen, DataBridge als Startprojekt setzen (Rechtsklick im Projektmappen-Explorer → Als Startprojekt festlegen, falls nicht schon aktiv).
  2. Im Dropdown neben dem grünen Play-Pfeil das Profil DataBridge wählen.
  3. F5 (Debuggen starten) statt Ctrl+F5.
  4. Breakpoints wie gewohnt setzen.

VS Code

VS Code braucht die Azure Functions Core Tools (func) und die Erweiterung Azure Functions (oder C# Dev Kit), um Attach/Debug über launchSettings.json anzubieten. Ohne Erweiterung reicht auch der direkte Weg:

  1. Terminal in src/DataBridge öffnen.
  2. func start (nutzt automatisch local.settings.json und den Port aus host.json/der Umgebung — bei Bedarf func start --port 7062 explizit angeben).
  3. Mit der Erweiterung C# Dev Kit: Debug: Attach to .NET Process ausführen und den laufenden func-/dotnet-Prozess auswählen. Mit der Azure Functions-Erweiterung genügt stattdessen F5 direkt im Projektordner, das startet func start automatisch im Debug-Modus.
  4. Breakpoints wie gewohnt setzen.

Danach in jeder IDE:

  • Der MCP-Server databridge-dev aus .mcp.json funktioniert unverändert (http://localhost:7062/api/mcp?code=local) — func start prüft den Function Key nicht, siehe MCP für die Testumgebung.
  • Eine Anfrage auslösen (z. B. POST http://localhost:7062/api/ExecuteJob?code=local, per Bruno, curl oder MCP run_job) und der Breakpoint hält an.

Logging

dev/local.settings.dev.json setzt kein APPLICATIONINSIGHTS_CONNECTION_STRING — es gibt also auch im Host-Modus keine Application Insights, an die etwas gesendet werden könnte. Alles, was die DataBridge loggt, geht direkt in die Konsole des lokalen Prozesses:

  • Rider: das Run-Fenster (bzw. Debug-Fenster mit Breakpoints) am unteren Rand.
  • Visual Studio: das Ausgabefenster (Ansicht → Ausgabe, Quelle „Debug“) sowie bei F5 das Konsolenfenster der Function-Host-Runtime.
  • VS Code: das Terminal, in dem func start läuft, bzw. der Debug Console-Tab bei Attach.

src/DataBridge/host.json setzt für die Kategorien DataBridge und Function den Log-Level Trace — dieselbe ausführlichste Stufe wie im Container (siehe Lokale Testumgebung → Logging). Weil hier keine Application Insights mitläuft, spielen die dortigen Sampling-/Puffer-Regeln (TELEMETRY_INFO_SAMPLE_RATE, TELEMETRY_CONTROL) keine Rolle — sie wirken nur auf den Versand an Application Insights, nicht auf die Konsolenausgabe.

GetChanges/Process*QueueItems steuern

Zwei unabhängige Schalter entscheiden, ob im Host-Modus etwas automatisch verarbeitet wird:

SchalterArgument bei up.sh --host/up.ps1 -HostModeWirkung
DATABRIDGE_GETCHANGESgetchangesAzureWebJobs.GetChanges.Disabled in der generierten local.settings.json
DATABRIDGE_PROCESSprocessAzureWebJobs.Process{Standard,High,Low}PriorityQueueItems.Disabled
dev\up.ps1 -HostMode mssql process             # Verarbeitung an, Timer aus
dev\up.ps1 -HostMode mssql getchanges process  # beides an
dev\up.ps1 -HostMode mssql                     # beides aus – Verarbeitung nur manuell per ExecuteJob
dev/up.sh --host mssql process              # Verarbeitung an, Timer aus
dev/up.sh --host mssql getchanges process   # beides an
dev/up.sh --host mssql                      # beides aus – Verarbeitung nur manuell per ExecuteJob

Beide Toggles aktivieren automatisch das Profil servicebus (siehe Service Bus), weil ohne Emulator weder GetChanges noch Process*QueueItems sinnvoll etwas zu tun hätten. Die Durable-Functions-Kette (StartGetChangesOrchestration, GetChangesOrchestrator, GetChangesActivity, JobState) bleibt immer deaktiviert.

Weil local.settings.json bei jedem --host-Aufruf neu generiert wird, reicht ein erneutes up.sh --host … mit anderen Toggles, um umzuschalten — die IDE muss dafür neu gestartet werden (Azure-Functions-Runtime liest local.settings.json nur beim Start).

Typischer Ablauf, um einen Job Ende-zu-Ende mit Breakpoints zu verfolgen:

  1. dev/up.sh --host mssql process (Windows: dev\up.ps1 -HostMode mssql process) — Datenbank, Verarbeitung und Service-Bus-Emulator, aber ohne Container-DataBridge.
  2. In der IDE debuggen starten (s. o.), Breakpoint z. B. in ProcessQueueMessageService setzen.
  3. Job manuell per ExecuteJob auslösen — Details, Job-Namen-Muster und Beispielaufruf unter Lokale Testumgebung → Einen Job manuell ausführen. IsActive: true ist dafür nicht nötig.
  4. getchanges zusätzlich nur nötig, wenn der Timer selbst (statt ExecuteJob) die Änderungen erkennen soll — dann muss der Job vorher per update_job auf IsActive: true gesetzt werden.

Service Bus einsehen

Drei Wege, in den Service-Bus-Emulator hineinzuschauen, ohne selbst Code zu schreiben:

Web-Oberfläche servicebus-explorer (empfohlen, auch zum aktiven Testen). Läuft automatisch mit, sobald das Profil servicebus aktiv ist (also auch über getchanges/process) — kein separater Start nötig. Zeigt Queues, Nachrichtenzahlen (aktiv/dead-lettered) und einzelne Nachrichten inkl. Body in einer grafischen Oberfläche:

http://localhost:8090   (Port konfigurierbar über SERVICEBUS_EXPLORER_PORT in dev/.env)

Es handelt sich um das Community-Tool Service-Bus-Emulator-Explorer von Tom Biddulph (nicht von Microsoft, kein Bestandteil des offiziellen Emulators) — als eigener Container servicebus-explorer im Compose-Stack mitgeliefert, per fertigem Image (ghcr.io/tombiddulph/service-bus-emulator-explorer), spricht intern mit servicebus über dieselben Connection-Strings wie die DataBridge selbst.

Anders als die MCP-Diagnose-Tools kann die Web-Oberfläche auch selbst Nachrichten auf eine Queue oder ein Topic legen (eigener Body, Content-Type, Custom Properties, Session-ID) — praktisch, um Process*QueueItems gezielt mit einer handgebauten Nachricht zu testen, ohne vorher GetChanges über einen echten Job laufen zu lassen.

MCP (kein zusätzliches Werkzeug nötig, gut für Automatisierung/Scripting). Der MCP-Server databridge-dev bietet schreibgeschützte Diagnose-Tools: list_queue_statuses/get_queue_status (Nachrichtenzahlen je Queue) und peek_* für die Metadaten wartender Nachrichten (u. a. Body-Größe, keine Inhalte — siehe MCP für die Testumgebung). Das läuft über den Admin-Client auf Port 5300, den ServiceBusService beim Emulator automatisch anhängt (siehe Service Bus).

Rohes REST/AMQP, z. B. per curl. Die Management-API des Emulators liegt auf http://localhost:5300; für eigene Skripte, die weder die Weboberfläche noch MCP nutzen sollen, reicht derselbe Connection-String wie oben.

2 - Gegen echtes Azure debuggen

Die DataBridge lokal mit Breakpoints gegen eine echte Azure-Instanz debuggen — konkret in Rider, Visual Studio und VS Code, inklusive Steuerung von GetChanges/Process*QueueItems.

Hier läuft kein Podman-Stack mit — die lokal gestartete DataBridge verbindet sich direkt mit einem echten Storage Account, einem echten Service Bus Namespace und den echten Quell-/Zielsystemen (BC, CE, NAV, SQL). Das ist der klassische Weg, um ein Problem aus einer konkreten Umgebung (z. B. dsyr-wysatest) lokal nachzuvollziehen oder mit dem Debugger zu untersuchen.

local.settings.json vorbereiten

  1. src/DataBridge/sample.local.settings.json nach src/DataBridge/local.settings.json kopieren (falls noch nicht vorhanden — die Datei ist in .gitignore, geht also nicht versehentlich in einen Commit).
  2. Die Platzhalter durch echte Werte aus dem Azure Portal bzw. Key Vault ersetzen: AzureWebJobsStorage (Storage-Account-Connection-String), ExportQueueServiceBus (Service-Bus-Connection-String) sowie die Connection-Strings/Secrets der Quell- und Zielsysteme, je nachdem was getestet werden soll. Diese Werte niemals committen und nicht in Chats/Tickets einfügen.
  3. Wenn enableManagedIdentity in der Zielumgebung aktiv ist (siehe Identity-Verbindungen bzw. SettingsService), fehlen dort Connection-Strings ganz — stattdessen AzureWebJobsStorage__accountName und ExportQueueServiceBus__fullyQualifiedNamespace setzen und lokal per az login angemeldet sein, damit DefaultAzureCredential greift. Das erfordert eine Rollenzuweisung für den eigenen Benutzer auf Storage und Service Bus (Data-Rollen, nicht nur Management), sonst schlägt der Verbindungstest beim Start fehl.

In der IDE starten

Identisch zum Podman-Host-Modus — alle drei IDEs nutzen dasselbe Projekt src/DataBridge/DataBridge.csproj und dasselbe Profil DataBridge aus src/DataBridge/Properties/launchSettings.json (startet mit --port 7062).

Rider

  1. Lösung src/DataBridge.slnx öffnen.
  2. Run-Profil DataBridge auswählen, dann auf das Käfer-Symbol (Debug) klicken bzw. Shift+F9.
  3. Breakpoints setzen, z. B. im Connector des Systems, das gerade untersucht wird.

Visual Studio

  1. src/DataBridge.slnx öffnen, DataBridge als Startprojekt setzen.
  2. Profil DataBridge im Dropdown neben dem Play-Pfeil wählen, dann F5.
  3. Breakpoints setzen.

VS Code

  1. Terminal in src/DataBridge öffnen, func start ausführen (liest local.settings.json automatisch).
  2. Mit C# Dev Kit: Debug: Attach to .NET Process auf den laufenden func-Prozess. Mit der Azure Functions-Erweiterung genügt F5 direkt im Projektordner.
  3. Breakpoints setzen.

Der MCP-Server databridge (nicht databridge-dev) aus .mcp.json zeigt per Voreinstellung auf http://localhost:7062 — passt also automatisch, solange kein DATABRIDGE_MCP_URL gesetzt ist, das auf eine andere Instanz zeigt.

Logging

Hier läuft Logging doppelt, weil local.settings.json einen echten APPLICATIONINSIGHTS_CONNECTION_STRING enthält (aus sample.local.settings.json übernommen und mit echten Werten gefüllt, siehe oben):

  1. Direkt in der IDE-Konsole — wie im Host-Modus gegen Podman: Rider-Run-Fenster, Visual-Studio-Ausgabefenster bzw. das func start-Terminal in VS Code. host.json setzt Trace für DataBridge/Function, also die volle Ausführlichkeit, unabhängig von Application Insights.
  2. In der echten Application Insights-Instanz — mit denselben Regeln wie in Produktion: gepuffertes Sampling, TELEMETRY_INFO_SAMPLE_RATE, TELEMETRY_CONTROL, siehe Betrieb → Logging. Trace-Einträge erreichen Application Insights dabei nie — nur die IDE-Konsole zeigt sie.

GetChanges/Process*QueueItems steuern

Anders als im Podman-Host-Modus gibt es hier keinen up.sh-Schalter — die App-Settings stehen direkt in local.settings.json und werden von Hand gesetzt:

{
  "Values": {
    "AzureWebJobs.GetChanges.Disabled": "true",
    "AzureWebJobs.ProcessStandardQueueItems.Disabled": "true",
    "AzureWebJobs.ProcessHighPriorityQueueItems.Disabled": "true",
    "AzureWebJobs.ProcessLowPriorityQueueItems.Disabled": "true"
  }
}

"true" deaktiviert die jeweilige Funktion, "false" bzw. Weglassen aktiviert sie. Vor dem Debuggen bewusst entscheiden:

  • Nur einen bestimmten Job untersuchen, sonst nichts verarbeiten: alle vier auf "true" lassen und stattdessen gezielt POST /api/ExecuteJob aufrufen (löst GetChanges für einen einzelnen Job aus, unabhängig vom Timer).
  • Den echten Timer-/Queue-Ablauf beobachten: die passenden Einträge auf "false" setzen. Das bedeutet aber, dass die lokal debuggte Instanz zusätzlich zu jeder produktiv laufenden Instanz derselben Umgebung Änderungen erkennt bzw. Queue-Nachrichten verarbeitet.

Podman- und Cloud-Settings parallel halten

src/DataBridge/local.settings.json ist für beide Debug-Varianten dieselbe Datei — wer öfter zwischen Podman-Host-Modus und Cloud-Debugging wechselt, verliert sonst bei jedem up.sh --host die mühsam eingetragenen echten Zugangsdaten (siehe Warnhinweis oben). Zwei Optionen:

Eigene Kopie + Copy-Befehl (empfohlen, geringer Aufwand). Einmalig eine zweite, selbst gepflegte Datei anlegen, die up.sh/up.ps1 nie anfassen — z. B. src/DataBridge/local.settings.cloud.json (Kopie von sample.local.settings.json mit echten Werten, siehe oben). Diese Namensform (local.settings.*.json) ist bereits über src/DataBridge/.gitignore ausgeschlossen, landet also nicht versehentlich in einem Commit. Vor dem Cloud-Debuggen einmal darüberkopieren:

Copy-Item src\DataBridge\local.settings.cloud.json src\DataBridge\local.settings.json -Force
cp src/DataBridge/local.settings.cloud.json src/DataBridge/local.settings.json

Der Rückweg ist kein manueller Schritt: Der nächste dev/up.sh --host/dev\up.ps1 -HostMode überschreibt local.settings.json ohnehin automatisch wieder aus der Podman-Vorlage (dev/local.settings.dev.json).

Getrennter Checkout/Git-Worktree. Für häufigen, unterbrechungsfreien Wechsel: einen zweiten Checkout des Repos ausschließlich fürs Cloud-Debuggen anlegen, mit eigener, dauerhaft gefüllter local.settings.json, komplett getrennt vom Ordner, in dem dev/up.sh --host läuft. Mehr Verwaltungsaufwand beim Einrichten, dafür kein Kopieren mehr im Alltag — einfach die passende IDE im jeweils anderen Ordner öffnen.