# Release v2.1

> Statische Schlüsselwerte, mehrere Ziel-Schlüssel, Sampling von Abhängigkeiten und ein mitgeliefertes Grafana-Dashboard.

---

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

---

## Was ist neu

### Neue Funktionen

- **Statische Schlüsselwerte für Lookups**: Ein Lookup kann jetzt gegen einen fest hinterlegten Wert aufgelöst werden, ohne dass dafür ein Quellfeld existieren muss. Dazu wird im Schlüssel (`Keyvalue`) statt eines `attributeName` ein `StaticValue` angegeben. Nützlich, wenn ein Lookup immer auf denselben Zieldatensatz zeigen soll (z.B. eine feste Kategorie oder ein Standard-Datensatz).

- **Mehrere Ziel-Schlüssel je Mapping mit Rangfolge**: Ein Table-Mapping bzw. ein Lookup kann nun mehrere Ziel-Schlüssel (`TargetKeys`) besitzen. Die Schlüssel werden anhand des neuen Felds `KeyRank` in aufsteigender Reihenfolge geprüft; sobald ein Schlüssel im Zielsystem einen Datensatz findet, wird dieser verwendet und die weiteren Schlüssel werden übersprungen. Damit lassen sich unterschiedliche Schlüssel gegen das CRM zulassen (z.B. zuerst eine externe ID, danach ersatzweise eine Nummer). Bestehende Mappings mit einem einzelnen `TargetKey` funktionieren unverändert weiter.

- **Automatische Anlage bei Lookups abschaltbar**: Über die neue Option `DoNotCreate` am Lookup lässt sich steuern, dass ein nicht gefundener Ziel-Datensatz **nicht** automatisch angelegt wird. Ist die Option gesetzt, wird der Lookup nur aufgelöst, wenn der Datensatz bereits existiert — andernfalls bleibt das Feld leer, statt einen neuen Datensatz zu erzeugen.

- **String-zu-Decimal-Konvertierung**: Der Decimal-Resolver akzeptiert jetzt auch Quellwerte vom Typ `string` und wandelt sie in einen Dezimalwert um (Interpretation im Format `en-US`, d.h. Punkt als Dezimaltrennzeichen). Leere Strings werden zu `null`, nicht konvertierbare Werte werfen wie bisher einen Fehler.

- **Vorab-Zwischenspeicherung von Lookups (Pre-Caching)**: Beim Verarbeiten eines Batches werden benötigte Lookup-Werte vorab gebündelt aufgelöst und zwischengespeichert. Dadurch werden wiederholte Einzelabfragen gegen das Zielsystem vermieden, was die Verarbeitung großer Änderungsmengen beschleunigt.

- **Sampling von Abhängigkeiten (Dependencies)**: Ausgehende Aufrufe an Quell- und Zielsysteme (D365 OData, SQL, Table Storage, Service Bus) werden von Application Insights automatisch als Abhängigkeiten erfasst und verursachten bisher den Großteil des Datenvolumens — bei minutengenauem Polling ein Vielfaches aller Log-Einträge zusammen. Diese Aufrufe werden nun gefiltert: Fehlgeschlagene sowie langsame Aufrufe werden immer vollständig gesendet, erfolgreiche und schnelle nur zu einem konfigurierbaren Anteil (Standard: 10 %). Das reduziert das tägliche Datenvolumen erheblich; Exceptions, Requests und alle Log-Einträge eines Fehler-Laufs bleiben unverändert vollständig erhalten. Steuerbar über die neuen Einstellungen `TELEMETRY_DEPENDENCY_SAMPLE_RATE` und `TELEMETRY_DEPENDENCY_SLOW_MS`; Details unter [Betrieb → Logging](../../betrieb/logging/).

  > **Zu beachten**
>
> Die Entscheidung fällt **pro Aufruf** in dem Moment, in dem der Aufruf endet — nicht pro Funktionsausführung wie beim Logging. Ein fehlgeschlagener Lauf enthält daher zwar garantiert den fehlgeschlagenen Aufruf, nicht aber zwangsläufig die erfolgreichen Aufrufe davor. Wird dieser Verlauf für eine Analyse benötigt, ist vorübergehend `TELEMETRY_CONTROL=TRACE_ALL` zu setzen.



- **Grafana-Dashboard für Application Insights**: Jede Installation legt jetzt automatisch ein vorkonfiguriertes Dashboard unter „Dashboards with Grafana" im Application-Insights-Blade an — mit Erfolgsraten je Funktion (GetChanges, Verarbeitung nach Priorität), Ausführungszahlen, Laufzeiten je Job sowie einer Übersicht der Exceptions nach Zeit und Typ. Das Dashboard wird ohne separate Aktivierung mit ausgeliefert.

- **Weitere Einstellungen bereits beim Deployment konfigurierbar**: Der Cron-Ausdruck des GetChanges-Timers sowie alle vier Telemetrie-Sampling-Einstellungen (`TELEMETRY_DEPENDENCY_SAMPLE_RATE`, `TELEMETRY_DEPENDENCY_SLOW_MS`, `TELEMETRY_INFO_SAMPLE_RATE`, `TELEMETRY_CONTROL`) lassen sich jetzt direkt als Bicep-Parameter bzw. im Marketplace-Installationsassistenten setzen, statt sie nachträglich manuell in den App-Settings der Function App zu pflegen. Im Marketplace-Assistenten sind sie unter **Product Settings** in die Bereiche *Function Settings*, *Telemetry*, *Alert* und *Preview* gruppiert.

### Fehlerbehebungen & Verbesserungen

#### Allgemein

- **Watermark wurde bei abweichend geschriebenem `WatermarkType` gelöscht**: Der Typvergleich war zeichengenau. Ein in der Tabelle *jobs* von Hand eingetragenes `DateTime` statt `datetime` (oder ein versehentliches Leerzeichen) führte dazu, dass die gespeicherte Watermark des Jobs **geleert** wurde. Da die DataBridge bei leerer Watermark den Filter-Block vollständig entfernt, las der betroffene Job anschließend das **komplette Quellsystem** — und zwar bei jedem Lauf erneut, ohne Fehlermeldung oder Warnung. Der Typ wird nun ohne Beachtung von Groß-/Kleinschreibung und ohne umgebende Leerzeichen erkannt; ein tatsächlich unbekannter Typ lässt die gespeicherte Watermark unangetastet und erzeugt eine **Warnung im Log**. Siehe Installationshinweise — betroffene Jobs sollten nach dem Update geprüft werden.

- **Deutlich weniger Zugriffe auf die Watermark-Tabelle**: Die Prüfung, welche Jobs laut Zeitplan fällig sind, holte für **jeden** aktiven Job eine eigene Abfrage aus der Tabelle *watermark*, obwohl dafür nur ein Zeitstempel benötigt wird. Diese Einzelabfragen sind durch eine gebündelte Abfrage ersetzt. Bei rund 220 aktiven Jobs sinkt die Zahl der Lesezugriffe von ~7.400 auf ~810 pro Stunde. Die Anzahl der Schreibzugriffe bleibt unverändert. Das entlastet Azure Table Storage und reduziert zusätzlich das Datenvolumen in Application Insights.

- **Watermark-Vergleich robuster**: Drei Detailprobleme in der Watermark-Auswertung wurden behoben. Zeitstempel werden nun zeitzonenunabhängig verglichen — bisher wurde die Zeitangabe in die lokale Zeit des Servers umgerechnet, was beim Typ `date` über eine Tagesgrenze springen und das Vergleichsergebnis je nach Betriebsstandort verändern konnte. Fehlt ein Änderungsmarker, bleibt die Watermark unverändert stehen statt einen Abbruch auszulösen. Und eine fehlende Watermark-Spalte in der Tabelle führt nicht mehr zu einem leeren Rückschreibewert.

- **`Validate`-Funktion auf async umgestellt**: Die Diagnose-Funktion `Validate` verwendete synchrone I/O (`WriteString`) sowie ein blockierendes `.Wait()`/`.Result` beim Warten auf die Initialisierung — beides ist mit dem ASP.NET Core-Modus nicht kompatibel. Sie ist jetzt vollständig auf `async/await` umgestellt.

- **Aussagekräftigeres Logging bei `ExecuteHttpRequest`**: Bei ad-hoc HTTP-Anfragen werden jetzt der HTTP-Statuscode und der Antwortinhalt getrennt protokolliert, was die Fehlersuche bei fehlgeschlagenen Requests erleichtert.

- **Erweiterte Auswertungs-Abfragen für Abhängigkeiten und Kosten**: Die Dokumentation enthält neue KQL-Abfragen für die langsamsten Abhängigkeiten, fehlgeschlagene Aufrufe nach Zielsystem sowie eine Volumenanalyse pro Tabelle zur Ursachensuche bei erreichter Daten-Obergrenze (Daily Cap). Siehe [Betrieb → Logging](../../betrieb/logging/).

#### BC & NAV

- **Statische Schlüsselwerte im BcConnector-Filter**: Die Schlüssel- und Filtererzeugung des Business-Central-Connectors berücksichtigt nun ebenfalls statische Schlüsselwerte (`StaticValue`), sodass die neuen Lookup-Funktionen auch gegen D365 BC funktionieren. Zusätzlich wurde ein Fehler behoben, durch den Schlüsselwerte vom Typ `string` (z.B. Nummernfelder) ohne umschließende Anführungszeichen in den OData-Filter geschrieben wurden — ein mehrteiliger Schlüssel mit einem String-Anteil führte dadurch zu einer ungültigen Filterabfrage gegen BC. Der Filter wird nun für `string`-Werte korrekt in Anführungszeichen gesetzt.

- **Korrekte Fehlermeldung im NavConnector**: Eine Fehlermeldung im NAV-Connector verwies fälschlich auf „BC-Communication" — sie lautet jetzt korrekt „NAV-Communication".

## Installationshinweise

Ein Update auf v2.1 erfordert **keine zwingenden Konfigurationsänderungen**. Die neuen Mapping-Funktionen (statische Schlüsselwerte, mehrere Ziel-Schlüssel, `DoNotCreate`) werden ausschließlich über die Mapping-Konfiguration in Azure Table Storage aktiviert und sind für bestehende Mappings optional — ohne Konfigurationsänderung bleibt das bisherige Verhalten erhalten.

Empfohlen wird jedoch eine **einmalige Sichtprüfung der Tabelle *jobs*** (siehe unten) — sie deckt eine Fehlkonfiguration auf, die bisher unbemerkt zu Vollabzügen geführt haben kann.

### Neue / geänderte App-Settings (Azure Function)

Beide Einstellungen sind optional. Ohne Konfiguration gelten die angegebenen Standardwerte, das Sampling von Abhängigkeiten ist also **ab dem Update automatisch aktiv**.

| Einstellung | Typ | Standard | Beschreibung | Pflicht |
|---|---|---|---|---|
| `TELEMETRY_DEPENDENCY_SAMPLE_RATE` | Integer (0–100) | `10` | Prozentualer Anteil der erfolgreichen und schnellen Abhängigkeits-Aufrufe, die an App Insights gesendet werden. Fehlgeschlagene und langsame Aufrufe sind davon nicht betroffen. | Nein |
| `TELEMETRY_DEPENDENCY_SLOW_MS` | Integer (ms) | `2000` | Schwellwert, ab dem ein Aufruf als „langsam" gilt und immer gesendet wird — auch bei Erfolg. | Nein |

Die bestehende Einstellung `TELEMETRY_CONTROL` wirkt nun zusätzlich auf Abhängigkeiten: `TRACE_ALL` deaktiviert auch deren Sampling, `TRACE_NONE` unterdrückt sie vollständig.

Diese beiden sowie die bereits bestehenden Einstellungen `TELEMETRY_INFO_SAMPLE_RATE`, `TELEMETRY_CONTROL` und `GetChangesTimerExpression` lassen sich ab dieser Version zusätzlich direkt beim Deployment setzen — als Bicep-Parameter (Beispielwerte in `bicep/params/databridge.sample.bicepparam`) oder im Marketplace-Assistenten unter **Product Settings**. Bei einem Update per Marketplace-Assistent führt ein erneuter Durchlauf zu keiner Änderung, solange die Standardwerte übernommen werden.

### Neue Azure-Ressourcen (Bicep)

- **Grafana-Dashboard** (`Microsoft.Dashboard/dashboards` + `dashboardDefinitions`): Vorkonfiguriertes Dashboard in Application Insights („Dashboards with Grafana"). Wird bei jedem Deployment fest mit angelegt, ohne Opt-out-Möglichkeit. Verursacht keine zusätzlichen Kosten; Abfragen laufen gegen die bestehende Application-Insights-Instanz.

### Zu prüfen nach dem Update: `WatermarkType` in der Tabelle *jobs*

Die Tabelle *jobs* ist einmalig daraufhin durchzusehen, ob im Feld `WatermarkType` ein abweichend geschriebener Wert steht — erwartet werden `datetime` oder `string`. Abweichungen wie `DateTime`, `Datetime` oder ein führendes Leerzeichen haben bis einschließlich der Vorversion dazu geführt, dass der betroffene Job seine Watermark verlor und bei **jedem** Lauf das komplette Quellsystem las.

Nach dem Update ist der Fall auch ohne Prüfung erkennbar: Ein nicht erkannter Typ erzeugt eine Warnung mit Jobnamen und dem hinterlegten Rohwert im Log.

**Was bei einem betroffenen Job zu erwarten ist:** Ist die Watermark bereits geleert, führt der erste Lauf nach dem Update noch einmal einen Vollabzug durch. Danach wird die Watermark korrekt fortgeschrieben und der Job arbeitet wieder inkrementell. Es ist also **kein manueller Eingriff** nötig — lediglich einmalig mit erhöhter Last für diesen Job zu rechnen.

### Hinweis zu bestehenden Auswertungen

Verworfene Abhängigkeiten werden vollständig entfernt und **nicht** über einen Hochrechnungsfaktor (`itemCount`) kompensiert. Bestehende Dashboards, Alerts oder KQL-Abfragen, die auf **absoluten Zählungen** oder Durchschnittslaufzeiten der Tabelle `dependencies` / `AppDependencies` basieren, liefern nach dem Update zu niedrige Werte und sind zu prüfen.

Besonders zu beachten sind **Fehlerquoten über die Tabelle `dependencies`**: Da fehlgeschlagene Aufrufe vollständig erhalten bleiben, erfolgreiche aber gesampelt werden, ist ein Ausdruck der Form `countif(success == false) / count()` nach dem Update **deutlich überhöht**. Solche Abfragen und darauf basierende Alerts sind zu entfernen oder auf die `requests`-Tabelle umzustellen, die keinem Sampling unterliegt.

Nicht betroffen sind:

- **Fehleranzahlen und Fehlerursachen** — fehlgeschlagene Aufrufe werden nie verworfen
- **Auswertungen langsamer Aufrufe** — diese werden ab dem Schwellwert immer gesendet
- **Requests, Exceptions, Traces und Custom Metrics** — unverändert

Für belastbare Mengenangaben sind die vorab aggregierten Custom Metrics zu verwenden, die keinem Sampling unterliegen.

### Container-Image

Falls die DataBridge containerisiert betrieben wird, ist das Image auf den neuen Tag zu aktualisieren:

`acrwysatest.azurecr.io/containered-connector:v2.1.0`

Die .NET-Basis bleibt unverändert (.NET 10, Isolated Worker) — es handelt sich lediglich um einen neuen Versions-Tag, kein Wechsel des Basis-Images.
