# 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.

---

Site [llms.txt](/llms.txt)

---

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](/entwicklung/architektur/) 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.

> **Podman überschreibt dieselbe Datei**
>
> `src/DataBridge/local.settings.json` ist die **einzige** Datei, aus der sowohl der Podman-Host-Modus
> als auch dieses Cloud-Setup lesen — es gibt keine zweite, von der Function-Runtime automatisch
> erkannte Datei. Läuft danach `dev/up.sh --host`/`dev\up.ps1 -HostMode` (siehe
> [Debuggen → Gegen Podman](../podman/)), wird die Datei **kommentarlos überschrieben** und die
> gerade eingetragenen echten Zugangsdaten sind weg. Wer beides abwechselnd nutzt, siehe
> [Podman- und Cloud-Settings parallel halten](#podman--und-cloud-settings-parallel-halten) weiter
> unten.



## 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`).

> **Das richtige Run-Profil auswählen**
>
> Leicht zu verwechseln mit einer automatisch angelegten **Test**-Konfiguration (Rider legt für jede
> Testklasse/jeden Testfall eine eigene an, sobald man sie einmal gestartet hat). Läuft aus Versehen
> ein Test statt der Function App, wirken Breakpoints in Connectoren/Services wie „tot“, und im Log
> tauchen Exceptions aus `DataBridge.Test.*` auf, die eigentlich von einem Test erwartet werden.
> Details und Beispiel siehe [Debuggen → Gegen Podman](../podman/#in-der-ide-starten). Vor dem
> Debuggen prüfen, dass oben rechts wirklich **DataBridge** ausgewählt ist.



**Rider**

1. Lösung `src/DataBridge.slnx` öffnen.
2. Run-Profil **DataBridge** auswählen, dann auf das Käfer-Symbol (Debug) klicken bzw.
   <kbd>Shift</kbd>+<kbd>F9</kbd>.
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 <kbd>F5</kbd>.
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 <kbd>F5</kbd> 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](/docs/betrieb/logging/). `Trace`-Einträge erreichen Application Insights
   dabei **nie** — nur die IDE-Konsole zeigt sie.

> **Läuft im selben Application-Insights-Workspace wie andere Instanzen**
>
> Die lokal debuggte Instanz sendet in **dieselbe** Application-Insights-Ressource wie jede andere
> Instanz, die denselben Connection-String nutzt (z. B. die produktiv laufende Function App). In der
> Transaktionssuche/Log-Analyse lässt sich die eigene Ausführung am ehesten über den Zeitpunkt und —
> sofern gesetzt — `cloud_RoleInstance` von den übrigen unterscheiden. Für eine gezielte Analyse
> `TELEMETRY_CONTROL=TRACE_ALL` in `local.settings.json` setzen, den Job manuell auslösen und danach
> wieder zurücksetzen (siehe [Betrieb → Logging → Tipps für die Fehlersuche](/docs/betrieb/logging/#tipps-für-die-fehlersuche)).



## 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:

```json
{
  "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.

> **Vorsicht bei geteilten Umgebungen**
>
> Anders als beim Podman-Stack gibt es hier keinen Reset auf Knopfdruck und keine Testdaten, die
> sich beliebig zurücksetzen lassen. Änderungen (Upserts, Watermarks, Queue-Nachrichten) wirken sich
> auf die echte Zielumgebung aus und sind für andere sichtbar, die dieselbe Umgebung nutzen. Vor dem
> Aktivieren von `GetChanges`/`Process*QueueItems` mit dem Team abstimmen, wer die Umgebung gerade
> sonst verwendet — im Zweifel zuerst [gegen Podman](../podman/) reproduzieren, bevor man gegen eine
> geteilte Cloud-Umgebung debuggt.



## 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:




<ul class="nav nav-tabs" id="tabs-4" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-04-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-04-00" role="tab"
          data-td-tp-persist="windows (powershell)" aria-controls="tabs-04-00" aria-selected="true">
        Windows (PowerShell)
      </button>
    </li><li class="nav-item">
      <button class="nav-link"
          id="tabs-04-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-04-01" role="tab"
          data-td-tp-persist="linux / macos" aria-controls="tabs-04-01" aria-selected="false">
        Linux / macOS
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-4-content">
    <div class="tab-body tab-pane fade show active"
        id="tabs-04-00" role="tabpanel" aria-labelled-by="tabs-04-00-tab" tabindex="4">
        <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-powershell" data-lang="powershell"><span style="display:flex;"><span>Copy-Item src\DataBridge\local.settings.cloud.json src\DataBridge\local.settings.json -Force
</span></span></code></pre></div>
    </div>
    <div class="tab-body tab-pane fade"
        id="tabs-04-01" role="tabpanel" aria-labelled-by="tabs-04-01-tab" tabindex="4">
        <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cp src/DataBridge/local.settings.cloud.json src/DataBridge/local.settings.json
</span></span></code></pre></div>
    </div>
</div>


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.
