Release v2.3

Managed Identity (system- und benutzer-zugewiesen) für D365BC und D365CE, Tabellen- und Spalten-Metadaten der SQL-Connectoren (MSSQL, MySQL, Oracle, PostgreSQL) über den MCP-Server, genauere Datentypen, Mapping-Abfrage per Name, schlankeres NAV-Logging, wieder funktionierendes Lesen aus PostgreSQL, MySQL und Oracle, behobene Abbrüche beim Schreiben von SQL-Datums-, Ganzzahl- und Fließkommafeldern nach BC/NAV/CE/OpenAPI und eine lokale Podman-Testumgebung mit Datenbanken, HTTP-Mocks und einem Service-Bus-Emulator für BC, NAV und OpenAPI.

Was ist neu

Neue Funktionen

  • Metadaten-Abfrage für die SQL-Connectoren: Die MCP-Tools list_connector_tables und get_connector_table_schema funktionieren jetzt auch für MSSQL, MySQL, Oracle und PostgreSQL. Bisher war das nur für BC, NAV, CE (Dataverse) und OpenAPI möglich, bei SQL-Verbindungen brach der Aufruf mit einer Fehlermeldung ab. Geliefert werden Spaltenname, Typ, Nullable, maximale Länge, bei Dezimalspalten Precision und Scale sowie der Primary Key — direkt aus dem Datenbank-Katalog (INFORMATION_SCHEMA, bei Oracle USER_*/ALL_*-Views).

    Über apiPath wird das Schema gewählt (MySQL: die Datenbank, Oracle: der Owner). Ohne Angabe gilt das Standard-Schema der Verbindung, sodass gleichnamige Tabellen in verschiedenen Schemas (z. B. dbo.Customers / archive.Customers) nicht vermischt werden. Die Metadaten werden zwischengespeichert; Schemaänderungen an der Datenbank werden erst nach einem Neustart der Function App sichtbar. Details: MCP-Server → Operationen.

  • Genaue .NET-Datentypen je Datenbank: Die Spaltentypen werden je Datenbank passend abgebildet — z. B. date als DateOnly, time als TimeSpan, Spalten mit Zeitzone als DateTimeOffset, Binärspalten als Byte[], MySQL BOOLEAN (tinyint(1)) als Boolean und Oracle NUMBER(p,0) je nach Stellenzahl als Int16/Int32/Int64. Die vollständige Übersicht steht unter MCP-Server → Operationen.

  • Managed Identity für D365CE (Dataverse): Die Verbindung kann statt über einen Connection-String mit Secret direkt über die Managed Identity der Function App aufgebaut werden. Dazu url (und optional clientid für eine benutzer-zugewiesene Identity) in der Connection angeben. Ein vorhandener connectionstring hat weiterhin Vorrang. Siehe D365CE.

  • Managed Identity für D365BC (Cloud): Neue Authentifizierungsart ManagedIdentity für HTTP-Konnektoren. Ohne clientId wird die system-zugewiesene, mit clientId die benutzer-zugewiesene Identity genutzt. Der Token wird automatisch erneuert, bevor er abläuft, und mit dem scope der Connection angefordert. Siehe D365BC.

  • Neuer Verbindungsparameter authmethod: Erlaubt es, die Authentifizierungsmethode ausdrücklich festzulegen (BasicAuthentication, OAuth2, APIKey, ManagedIdentity). Ohne Angabe bleibt das bisherige Verhalten unverändert. ManagedIdentity wird nie automatisch aus fehlenden Zugangsdaten abgeleitet, damit eine unvollständige Connection weiterhin sofort mit einem klaren Fehler abbricht. Siehe Verbindungen.

Fehlerbehebungen & Verbesserungen

Allgemein

  • Felder fehlten gelegentlich in der Verarbeitung: Wurden die Mappings neu geladen, während gleichzeitig Änderungen gelesen oder Nachrichten verarbeitet wurden, konnte ein Job auf ein noch unvollständiges Mapping treffen. Einzelne Felder, z. B. die Kontaktnummer einer Firma, wurden dann nicht übertragen. Die Mappings werden jetzt vollständig aufgebaut und erst danach aktiv geschaltet.
  • Service Bus: Skalierung ohne Managed Identity: Im schlüsselbasierten Modus (Standard, enableManagedIdentity nicht gesetzt) setzt das Bicep-Deployment jetzt TARGET_BASED_SCALING_ENABLED=0. Der Host skaliert dann direkt über den Metrics Monitor, und die bisherige Warnung zum Target-based Scaling im Log entfällt. Siehe Umgebungsvariablen.
  • Mapping-Abfrage über den Namen: Das MCP-Tool get_mapping und der HTTP-Endpunkt GET /mapping/{name} finden ein Mapping jetzt über seinen Namen — also den Namen, auf den ein Job verweist und unter dem list_mappings es auflistet. Bisher wurde nur der RowKey des ersten Feldeintrags verglichen, sodass ein Mapping über seinen Namen meist nicht gefunden wurde. Die bisherige Suche über den RowKey funktioniert weiterhin.
  • get_connector_table_schema akzeptiert jetzt auch den kombinierten Tabellennamen: Bei BC/NAV/CE/OpenAPI wird der API-Pfad in Jobs/Mappings üblicherweise zusammen mit der Tabelle geschrieben (z. B. v2.0/customers). Wurde dieser kombinierte Wert unverändert als tableName übergeben und apiPath weggelassen, schlug die Metadaten-Abfrage mit einer schwer deutbaren Exception fehl (Could not read Metadata for path). Das Tool trennt den API-Pfad jetzt selbst ab, wenn apiPath leer bleibt und tableName einen / enthält — Aufrufe mit getrennten Parametern funktionieren unverändert.
  • Nachvollziehbare MCP-Aufrufe im Log: Jeder MCP-Aufruf schreibt eine Logzeile mit dem Namen der Operation und — wo vorhanden — dem gelesenen Job, Mapping bzw. der Connection und Tabelle, z. B. MCP get_connector_table_schema: connection=oracle-dev, table=Account. Datensatzinhalte oder Zugangsdaten werden nicht geloggt.
  • Aktualisierte Abhängigkeiten (u. a. Azure.Data.Tables, Azure.Messaging.ServiceBus, Azure.Security.KeyVault.Secrets 4.11.2, Microsoft.IdentityModel.Tokens, Microsoft.OData.Core/Microsoft.OData.Edm auf 9.0.0, Microsoft.Data.SqlClient 7.1.1, MySql.Data 26.10.0, Oracle.ManagedDataAccess.Core 23.26.400, Microsoft.OpenApi 3.11.0, ModelContextProtocol 2.3.0, Durable-Functions-Extension 1.20.1 — rein intern, keine Verhaltensänderung). System.Security.Cryptography.Xml steht auf 10.0.14 und schließt damit mehrere als „hoch“ eingestufte Sicherheitslücken der Vorversion.

D365CE (Dataverse)

  • Fehlender oder inaktiver Alternativschlüssel wird nicht mehr als „Datensatz nicht gefunden“ gewertet: Ist der in TargetKey verwendete Schlüssel in Dataverse nicht definiert oder nicht aktiv, bricht die Verarbeitung jetzt mit einem Fehler ab. Die Nachricht wird wiederholt und landet anschließend in der Dead-Letter-Queue. Bisher wurde der Datensatz in diesem Fall als nicht vorhanden behandelt und neu angelegt, was zu Dubletten führen konnte. Siehe D365CE.
  • Fehler beim Nachschlagen eines Datensatzes führten still zu falschen Daten: Schlug das Lesen des bestehenden Zieldatensatzes fehl, etwa durch Throttling (Service-Protection-Limits), Timeout, Netzwerk- oder Rechtefehler, wurde das bisher wie „Datensatz existiert nicht“ behandelt. Die Folgen blieben unbemerkt: Löschungen wurden übersprungen und die Nachricht als erledigt abgeschlossen, Felder mit leerem Quellwert wurden im Ziel nicht geleert, und Lookups mit DoNotCreate konnten eine bestehende Referenz leeren. Jetzt gilt nur noch die Dataverse-Meldung „Datensatz nicht gefunden“ als solcher; jeder andere Fehler wird mit Details geloggt, die Nachricht wiederholt und notfalls in die Dead-Letter-Queue gelegt.
  • Nachgeschlagene Werte wurden nicht aktualisiert, wenn sie beim ersten Lesen noch fehlten: Lookups mit UseCache (z. B. die BC-Kontaktnummer der Firma auf Kontakten und Verkaufschancen) speicherten auch ein leeres Ergebnis und behielten einen einmal gelesenen Wert bis zum Neustart der Function App. War die Nummer beim ersten Lesen noch nicht aus BC zurückgeschrieben, wurde das Feld deshalb auch danach leer übertragen. Leere Ergebnisse werden jetzt nicht mehr gespeichert, und beim Lesen der Änderungen ersetzt ein frisch gelesener Wert immer den gespeicherten. Nicht mehr vorhandene Datensätze werden aus dem Zwischenspeicher entfernt.
  • Boolean-Felder aus Ganzzahlen befüllen: Ja/Nein-Felder akzeptieren jetzt auch die Quelltypen byte (z. B. SQL tinyint) und int32 (0 = Nein, sonst Ja). Statusfelder (statecode) akzeptieren zusätzlich byte.

BC, NAV & OpenAPI

  • HTTP-Konnektoren (BC, NAV, OpenAPI) konnten nach dem Start dauerhaft ausfallen: Verarbeiteten mehrere Queue-Nachrichten gleichzeitig ihren ersten Aufruf an dasselbe Zielsystem, richteten sie den gemeinsamen HTTP-Client parallel ein. Das führte zu Fehlern wie Object reference not set to an instance of an object oder This instance has already started one or more requests. Danach blieb der Client unvollständig eingerichtet (z. B. ohne Authentifizierung), und alle weiteren Nachrichten an dieses System schlugen bis zum Neustart der Function App fehl. Die Einrichtung ist jetzt gegen parallelen Zugriff geschützt, und eine fehlgeschlagene Einrichtung wird beim nächsten Aufruf wiederholt.
  • Update nach BC oder NAV schlug fehl, wenn ein Zielfeld dort bereits leer war: War ein Feld im bestehenden BC- oder NAV-Zieldatensatz null (z. B. ein noch nicht gesetztes Abschlussdatum) und hatte sich irgendein anderes Feld des Datensatzes geändert, brach die Aktualisierung mit einer NullReferenceException ab. Der interne Änderungsvergleich ging fälschlich davon aus, dass ein vorhandenes Feld nie leer sein kann. Behoben.
  • BC/NAV: Update mit TargetKey vom Typ Filter schlug bei Guid- oder Zahl-Schlüsseln fehl: Der Schlüssel aus KeyAttributeFromExisting wurde immer in Hochkommas gesetzt (z. B. customers('1111…')). Bei Schlüsselfeldern vom Typ Guid oder Zahl, etwa dem BC-Feld id, ergab das eine ungültige Anfrage. Der Schlüssel wird jetzt passend zum Feldtyp aus den Metadaten geschrieben, und Hochkommas im Wert werden maskiert. Fehlt das Feld im bestehenden Datensatz, bricht die Verarbeitung mit einer klaren Fehlermeldung ab statt mit einer NullReferenceException.
  • BC: Tabellen-Metadaten wurden zwischen API-Pfaden vermischt und nicht gefundene Tabellen dauerhaft zwischengespeichert: Der Metadaten-Cache unterschied Tabellen nur nach ihrem Namen, nicht nach dem API-Pfad. Gab es eine Tabelle (z. B. customers) unter einem API-Pfad nicht, unter einem anderen aber schon, konnte das Ergebnis des einen Pfads für den anderen verwendet werden. War eine Tabelle beim ersten Zugriff noch nicht in $metadata enthalten (z. B. weil eine Extension erst später veröffentlicht wurde), blieb dieser Fehlschlag bis zum Neustart der Function App bestehen. Der Cache unterscheidet jetzt nach API-Pfad und Tabelle. Nicht gefundene Tabellen werden nicht mehr gespeichert, beim nächsten Aufruf wird $metadata neu gelesen.
  • NAV: Metadaten nicht mehr im Log, klare Fehlermeldung: Der NAV-Konnektor hat beim Laden der Metadaten die komplette $metadata-Antwort auf Level Information geloggt. Bei echten NAV-Installationen sind das oft mehrere hundert KB bis einige MB je Neustart. Das erzeugte unnötiges Log-Volumen in Application Insights und wurde dort ohnehin abgeschnitten. Der Konnektor verhält sich jetzt wie der BC-Konnektor und loggt nur noch die Anzahl der gefundenen EntitySets. Außerdem prüft er den Statuscode. Antwortet der Server nicht mit Erfolg (z. B. 401 oder 500), erscheint Could not read Metadata from <URL> (StatusCode: …) statt eines schwer deutbaren Parse-Fehlers. Die Metadaten werden weiterhin tolerant gelesen.
  • NAV: Später veröffentlichte Tabellen wurden erst nach einem Neustart erkannt: Fehlte eine Tabelle beim ersten Laden der Metadaten, blieb das veraltete Modell bis zum Neustart der Function App aktiv. Jetzt werden die Metadaten beim nächsten Aufruf neu gelesen. Außerdem wird $metadata nicht mehr doppelt abgerufen, wenn sowohl die Tabellenliste als auch die Tabellen-Metadaten benötigt werden.
  • Aktualisieren eines bestehenden Datensatzes in einer OpenAPI-Zielressource schlug grundsätzlich fehl: Jeder Schreibvorgang, der einen Datensatz aktualisiert statt neu anzulegen (PATCH/PUT), brach mit einer NullReferenceException ab — betroffen war der reguläre Verarbeitungspfad ohne Antwort-Job, also der Normalfall. Ursache war eine fehlende Null-Prüfung beim Zusammenbauen des Request-Bodys. Neuanlagen (POST) waren nicht betroffen. Behoben.
  • OpenAPI: Aktualisieren und Löschen mit TargetKey vom Typ Filter gingen an eine falsche URL: Der Konnektor setzte den Suchfilter selbst als Schlüssel in die Item-URL ein. Jetzt wird zuerst der passende Datensatz gesucht und dessen Schlüssel verwendet: das Feld aus KeyAttributeFromExisting, sonst der Primärschlüssel aus der Spezifikation (id, uuid …). Findet der Konnektor beim Löschen keinen Datensatz, schreibt er eine Warnung ins Log und sendet kein DELETE. Der Fehler bestand seit v2.2.
  • OpenAPI: Gleichnamige Ressourcen verschiedener Connections wurden vermischt: Boten zwei OpenAPI-Verbindungen eine Ressource mit demselben Namen an (z. B. clients), verwendete die zweite das Schema der ersten. Der Fehler bestand seit v2.2. Jetzt wird das Schema je Spezifikation zwischengespeichert.
  • Doku OpenAPI-Konnektor korrigiert: Der Hinweis, dass der Konnektor die Spezifikation aus einer festen lokalen Datei lädt, war veraltet. Die Spezifikation wird über openApiSpecUrl geladen. Neu dokumentiert sind zwei bekannte Einschränkungen (siehe unten).

SQL-Konnektoren (MSSQL, PostgreSQL, MySQL, Oracle)

  • PostgreSQL, MySQL und Oracle als Quelle: Lesen schlug grundsätzlich fehl: Der Konnektor erzeugte eine ungültige Abfrage, weil zwischen der letzten Spalte und FROM das Leerzeichen fehlte (z. B. …,RevenueFROM Account). Jeder Job mit einer dieser Datenbanken als Quelle brach mit einem Datenbankfehler ab (PostgreSQL: column … does not exist, MySQL: Unknown column, Oracle: ORA-00904). Der Fehler bestand seit v2.2. MSSQL war nicht betroffen. Behoben.
  • MSSQL: Spaltennamen werden immer in eckige Klammern gesetzt: Alle Spalten aus dem Mapping und das WatermarkField werden jetzt in [...] eingeschlossen, nicht mehr nur Namen mit Leerzeichen. Damit funktionieren auch reservierte Wörter wie Order oder Key als Spaltenname. Für Mappings mit reinen Spaltennamen ändert sich nichts. Ausdrücke oder Aliasse als SourceField wurden schon vorher nicht unterstützt. Siehe MSSQL.
  • Datumsfelder aus SQL-Quellen (DATE-Spalte) nach BC, NAV, Dataverse (CE) oder OpenAPI schlugen fehl: Stammte ein Datumswert aus einer MSSQL-, PostgreSQL-, MySQL- oder Oracle-Spalte vom Typ DATE (intern als DateOnly geführt) und das Zielfeld lag bei BC, NAV, Dataverse oder einer OpenAPI-Zielressource, brach die Verarbeitung mit Source Type not yet implemented ab. Die Datums- und Datum/Zeit-Resolver kannten nur ihren eigenen internen Typnamen „Date“, nicht „DateOnly“. Betroffen waren ausschließlich Jobs mit einer SQL-Datenbank als Quelle. Behoben, indem alle Datums-Resolver jetzt beide Typnamen akzeptieren.
  • Ganzzahl- und Fließkommafelder aus SQL-Quellen mit TINYINT/SMALLINT/BIGINT/REAL schlugen fehl: Aus demselben Grund brach die Verarbeitung mit Source Type not yet implemented ab, wenn eine SQL-Spalte vom Typ TINYINT, SMALLINT, BIGINT oder einem kleinpräzisen FLOAT/REAL in ein Ganzzahl-, Dezimal- oder Fließkomma-Zielfeld bei BC, NAV oder Dataverse geschrieben wurde. Auch hier waren nur Jobs mit SQL als Quelle betroffen. Behoben.
  • MySQL: vorzeichenbehaftete TINYINT-Spalten in Ganzzahlfelder: Der MySQL-Treiber liefert diese Spalten als SByte. Beim Schreiben in ein Ganzzahlfeld bei BC, NAV, Dataverse oder OpenAPI brach die Verarbeitung mit Source Type not yet implemented ab. Behoben.

Entwickler-Features

Diese Neuerungen betreffen nur die Entwicklung der DataBridge im Repository, nicht den Betrieb einer Instanz.

  • Lokale Podman-Testumgebung: dev/up.sh bzw. dev/up.ps1 startet die DataBridge aus dem aktuellen Quellcode zusammen mit Azurite und wahlweise MSSQL, PostgreSQL, MySQL und Oracle (dev/up.sh mssql oracle, dev/up.sh all). In jeder Datenbank werden dieselben Beispieltabellen Account, Opportunity und OpportunityProduct mit Testdaten angelegt, die möglichst viele Datentypen abdecken. Connections, Jobs für jede Datenbank-Kombination und Mappings werden automatisch erzeugt. Details: Entwicklung → Podman-Testumgebung.
  • HTTP-Mocks für Business Central, NAV und OpenAPI: Die Testumgebung kann zusätzlich einen WireMock-Container starten, der BC (OAuth), NAV (Basic) und eine OpenAPI-Beispiel-API (API-Key) nachbildet. Die Mocks sind einzeln wählbar und lassen sich mit Datenbanken mischen (dev/up.sh mssql bc openapi, all für alles). WireMock startet nur, wenn mindestens ein Mock gewählt ist. Er lädt nur die Regeln der gewählten Mocks. Die Regeln decken den ganzen HTTP-Ablauf der Konnektoren ab: Verbindungstest, $metadata bzw. Spezifikation, Lesen mit Paging, Upsert mit Lookup, PATCH oder POST, sowie Löschen. Jeder Mock bildet jetzt alle drei Beispieltabellen ab (Account, Opportunity, OpportunityProduct — zuvor nur Account); Connections, Jobs und Mappings SQL ↔ Mock werden für alle drei automatisch angelegt. Was die DataBridge gesendet hat, zeigt das Anfrage-Protokoll unter localhost:8089/__admin/requests. Details: Entwicklung → Podman-Testumgebung.
  • MCP-Server databridge-dev: Die .mcp.json enthält einen zweiten Server, der fest auf die lokale Testumgebung zeigt. So stehen in Claude Code Cloud-Instanz (databridge) und Testumgebung (databridge-dev) nebeneinander zur Verfügung. Details: Entwicklung → MCP für die Testumgebung.
  • Neuer Dokumentationsbereich „Entwicklung“ mit der Beschreibung beider Werkzeuge.
  • Architektur im Detail: Die bisher nur intern gepflegte technische Detaildokumentation (Systemkontext, Bicep-Module, DI und host.json, HTTP- und Nachrichten-Referenz, Sequenzdiagramme, Abhängigkeiten, Fähigkeiten-Katalog) ist überarbeitet, auf den Stand 2.3 gebracht und unter Entwicklung → Architektur im Detail veröffentlicht. Die Übersicht unter Überblick → Architektur verweist darauf. Nebenbei korrigiert: „Wie es funktioniert“ nannte einen Timer-Takt von zwei Minuten (tatsächlich 15 Sekunden) und beschrieb die Transitive-Queues als automatische Wiederholungs-Queue.
  • Service-Bus-Emulator, schaltbare Verarbeitung, Debug-Modus: Die Testumgebung hat jetzt einen Service-Bus-Emulator (Profil servicebus), damit Jobs auch lokal von Anfang bis Ende laufen können. GetChanges (Timer) und Process*QueueItems lassen sich einzeln zuschalten (dev/up.sh mssql process), und dev/up.sh --host (bzw. dev\up.ps1 -HostMode) startet die Umgebung ohne den databridge-Container, damit sich ein lokal laufender Prozess mit dem Debugger daran hängen lässt. Details: Entwicklung → Podman-Testumgebung und Entwicklung → Debuggen.
  • Web-Oberfläche für den Service-Bus-Emulator: Läuft automatisch mit, sobald das Profil servicebus aktiv ist (http://localhost:8090, Port über SERVICEBUS_EXPLORER_PORT konfigurierbar) — zeigt Queues, Nachrichtenzahlen und einzelne Nachrichten grafisch an. Community-Tool Service-Bus-Emulator-Explorer, nicht von Microsoft. Der klassische Service Bus Explorer funktioniert mit dem Emulator nicht. Details: Entwicklung → Debuggen → Gegen Podman.
  • Fix: dev/down.sh/dev/down.ps1 ließen Service-Bus- und databridge-Container zurück. Die beiden Skripte kannten nur die Datenbank- und wiremock-Profile, nicht die seit dieser Version existierenden Profile servicebus und databridge — ein Reset (down -v) räumte deshalb servicebus, servicebus-db, servicebus-explorer und den databridge-Container nicht mit auf. Behoben, indem beide Profile in die feste Profil-Liste aufgenommen wurden.
  • Azurite-Connection-String direkt aus up.sh/up.ps1: Die Start-Zusammenfassung gibt jetzt den vollständigen, einsatzbereiten Connection-String für den Azure Storage Explorer aus, statt nur UseDevelopmentStorage=true. Details zum Verbinden: Entwicklung → Podman-Testumgebung → Azurite einsehen.
  • Fix: docker build aus einem frischen Checkout schlug fehl. Das Dockerfile kopierte Directory.Packages.props nicht vor dem dotnet restore-Schritt, wodurch das zentrale Paket-Versionsmanagement (ManagePackageVersionsCentrally) ins Leere lief (NU1015). Betraf nur den lokalen Container-Build (dev/up.sh/dev/up.ps1, src/compose.yml); die produktive Auslieferung baut nicht über dieses Dockerfile. Behoben.
  • Fix: dev\up.ps1/dev\down.ps1 unter Windows. Nach einem podman machine stop blieb eine Socket-Datei liegen, an der beim nächsten Start win-sshproxy scheiterte. Ohne die Docker-API-Pipe brach danach jeder podman compose-Aufruf ab. Beide Skripte räumen die Datei jetzt vor dem VM-Start weg und warten, bis Compose die VM erreicht. down.ps1 -Reset startet eine gestoppte VM selbst, down.ps1 ohne -Reset endet bei gestoppter VM ohne Fehler. Unter Windows PowerShell 5.1 brach up.ps1 außerdem ab, weil Compose seinen Fortschritt auf stderr schreibt, und zeigte Umlaute verstümmelt an. Beides behoben; die Skripte laufen unter PowerShell 7 und 5.1. Details: Entwicklung → Podman-Testumgebung → Fehlersuche.
  • Doku-Website auf Docsy 0.18.0: Das Theme ist mit dem Umzug des Docsy-Projekts unter github.com/docsy/docsy erreichbar; der Hugo-Modulpfad, die Mermaid-Einstellung (jetzt ein Docsy-Plugin) und Dart Sass (1.105.0) sind angepasst. Inhalt und Darstellung der Seiten bleiben gleich.
  • Build bricht bei NuGet-Paketen mit bekannten Sicherheitslücken ab. NuGet Audit prüft jetzt alle Projekte inklusive transitiver Pakete, und Treffer ab Schwere „moderate“ gelten als Fehler statt als Warnung („low“ bleibt eine Warnung) — lokal, im Dockerfile und in der Pipeline. Details: Entwicklung → Architektur → Abhängigkeiten.

Bekannte Einschränkungen

  • OpenAPI – CheckList: Der Diagnose-Endpunkt meldet für OpenAPI-Mappings fälschlich „could not find table“. GetTableNames liefert die Pfade der Spezifikation (/v1/customers) statt der Ressourcennamen (customers). Das Lesen und Schreiben ist nicht betroffen.
  • OpenAPI – Primärschlüssel: get_connector_table_schema weist bei OpenAPI keinen Primärschlüssel aus. Intern erkennt der Konnektor ihn weiterhin am Property-Namen.
  • PostgreSQL/Oracle – CheckList: Der Diagnose-Endpunkt meldet für Mappings mit PostgreSQL- oder Oracle-Tabellen fälschlich „could not find table“. Der Vergleich der Tabellennamen berücksichtigt nicht, dass PostgreSQL Namen kleingeschrieben und Oracle großgeschrieben ablegt. Das Lesen ist nicht betroffen.
  • BC/NAV – Zeitstempel: In den Metadaten werden Edm.DateTimeOffset-Felder wie lastModifiedDateTime intern mit demselben Typnamen geführt wie Edm.Date. Das betrifft nur die interne Typkennzeichnung des Quellwerts; die Uhrzeit geht dabei nachweislich nicht verloren, da die Datums-Resolver den tatsächlichen Wert unabhängig von dieser Kennzeichnung parsen.

Installationshinweise

Update von ZIP-Paket bzw. Container-Image (containered-connector:v2.3.0). Keine neuen Azure-Ressourcen. Das Bicep-Deployment setzt im schlüsselbasierten Modus zusätzlich das App-Setting TARGET_BASED_SCALING_ENABLED=0. Bei einem reinen ZIP- oder Image-Update ohne erneutes Deployment fehlt es nur, dann bleibt die Warnung im Log, die Funktion ist davon nicht betroffen.

Die Metadaten der SQL-Connectoren liefern gegenüber früheren Vorabständen teils andere Typnamen (z. B. DateOnly statt DateTime für date-Spalten). Das betrifft nur die Ausgabe von get_connector_table_schema; das Lesen von Daten ändert sich dadurch nicht.

Breaking Changes & Migrationsschritte

Verhaltensänderung bei CE-Jobs: Ist der in TargetKey verwendete Alternativschlüssel in Dataverse nicht definiert oder nicht aktiv, landen Nachrichten ab 2.3 in der Dead-Letter-Queue, statt dass der Datensatz neu angelegt wird.

  1. Vor dem Update für jeden CE-Zieljob mit CustomKey prüfen, dass der Alternativschlüssel in Dataverse existiert und aktiv ist (Power Apps → Tabelle → Schlüssel, Status „Aktiv“).
  2. Nach dem Update die Dead-Letter-Queues beobachten. Nachrichten mit einem Schlüsselfehler nach dem Aktivieren des Schlüssels erneut einreihen.

Verhaltensänderung bei CE-Zielen unter Last: Fehler beim Nachschlagen eines Zieldatensatzes (z. B. Throttling durch die Dataverse-Service-Protection-Limits) werden nicht mehr verschluckt, sondern lösen eine Wiederholung der Nachricht aus. Bei stark ausgelasteten Umgebungen können deshalb mehr Wiederholungen und, wenn die Limits länger anhalten, Einträge in der Dead-Letter-Queue auftreten — bisher wurden in diesen Fällen still falsche oder unvollständige Daten geschrieben. Diese Nachrichten nach Abklingen der Last erneut einreihen.

Managed Identity nutzen (optional)

Die Identity muss im jeweiligen Zielsystem berechtigt werden, das Bicep-Deployment erledigt das nicht:

  1. D365CE: Identity in der Dataverse-Umgebung als Anwendungsbenutzer anlegen und eine Sicherheitsrolle zuweisen.
  2. D365BC: Identity in Business Central unter Microsoft-Entra-Anwendungen anlegen, aktivieren und Berechtigungssätze zuweisen.
  3. Connection anpassen: für BC "authmethod": "ManagedIdentity" setzen, für CE url statt connectionstring verwenden.