From e5122c677fcf2cd0136f8aa5a3e91a36801007ff Mon Sep 17 00:00:00 2001 From: Meik Date: Fri, 3 Jul 2026 00:35:20 +0200 Subject: [PATCH] docs: document final 26.1 migration process --- docs/matrix42-26-1-extension-migration.md | 115 +++++++++++++++++----- 1 file changed, 92 insertions(+), 23 deletions(-) diff --git a/docs/matrix42-26-1-extension-migration.md b/docs/matrix42-26-1-extension-migration.md index 8f9a44f..f2124b6 100644 --- a/docs/matrix42-26-1-extension-migration.md +++ b/docs/matrix42-26-1-extension-migration.md @@ -108,6 +108,28 @@ Beim Portieren eines Legacy-Pakets: 3. Extension-/Assembly-ID beibehalten, wenn ein Update statt einer Neuinstallation gewollt ist. 4. Operation-IDs nur dann aendern, wenn bewusst neue Operationen entstehen sollen. 5. Obsolete oder entfernte Schema-Attribute aus 26.1 entfernen. +6. Nach der ersten lauffaehigen Version die Webservice-Operationen in Matrix42 synchronisieren, exportieren und die synchronisierten Contracts in die Paketdateien mergen. + +Wichtiges finales Learning zu Webservice-Operationen: + +- Wenn ein Endpoint nur nach "Service synchronisieren" korrekt funktioniert, sind die `PLSLWebServiceOperation`-Contracts im Paket nicht mehr synchron zum Controller. +- Die synchronisierten Operationen exportieren und mit den bestehenden Paketdateien mergen. +- Bestehende `PLSLWebServiceOperation.ID`s nicht durch Export-IDs ersetzen, sonst entstehen auf Bestandssystemen doppelte Operationen. +- Bestehende `PDRAudienceClass.ID`s ebenfalls erhalten. +- Nur fachliche Operation-Felder uebernehmen: `ResponseContract`, `RequestContract`, `Name`, `RouteTemplate`, `SupportedOperation`, `Type`, `IsPublic`. +- Neue Operationen, die bisher nicht im Paket vorhanden waren, duerfen die exportierten IDs verwenden, wenn sie aus dem Zielsystem stammen, auf dem sie bereits synchronisiert wurden. +- Operation-Dateien nach Operation benennen, z. B. `getticketlist.dat`, `getpickup.dat`, `isalive.dat`. Das erleichtert Reviews und verhindert Verwechslungen mit generischen `02-01-xxxx PLSLWebServiceOperationType.dat`-Dateien. +- Jede Datei aus `PackageTemplate/install/0002_WebServiceOperation` muss in `PackageTemplate/install.xml` referenziert sein. + +Validierung: + +```powershell +# XML parsebar? +python -c "import pathlib,xml.etree.ElementTree as ET; [ET.parse(p) for p in pathlib.Path('PackageTemplate/install/0002_WebServiceOperation').glob('*.dat')]" + +# Debug-Paket bauen und pruefen, ob alle Operation-Dateien im Paket liegen +dotnet build "C:\Workspace\C4IT FASD\F4SD_M42WebApi\C4IT - F4SD - M42WebApi.sln" -c Debug +``` Konkretes 26.1-Learning: @@ -224,7 +246,7 @@ Bewaehrt: - Datenendpoints geben direkte Nutzdaten zurueck, z. B. `Task>`, `Task` oder `Task`. - Leere Listen duerfen nicht `null` sein. -- `isAlive` gibt `IHttpActionResult` mit `StatusCodeResult(HttpStatusCode.NoContent)` zurueck. +- `isAlive` gibt `IHttpActionResult` mit einem expliziten HTTP-204-Response zurueck. Healthcheck: @@ -232,7 +254,13 @@ Healthcheck: [Route("isAlive"), HttpGet] public IHttpActionResult isAlive() { - return new StatusCodeResult(HttpStatusCode.NoContent); + var response = new HttpResponseMessage(HttpStatusCode.NoContent) + { + RequestMessage = Request + }; + response.Headers.ConnectionClose = true; + + return ResponseMessage(response); } ``` @@ -266,28 +294,63 @@ Regel: ## Routen und Parameterbindung -Wichtiges spaetes Learning: Der Matrix42 `m42Services`-Gateway kann Query-Parameter auch dann an die Methode binden, wenn die Controller-Route path-basierte Platzhalter hat. +Finales Learning: Fuer Legacy-Kompatibilitaet muessen Route, `PLSLWebServiceOperation.RouteTemplate`, `[FromUri]` und die alten Client-URLs zusammen betrachtet werden. -Beispiel im Code: +Bewaehrte Regeln: + +- Die Route-Attribute aus der funktionierenden Legacy-Version uebernehmen. +- Query-basierte Legacy-Endpoints bleiben query-basiert, z. B. `[Route("getTicketList")]`. +- Path-basierte Legacy-Endpoints bleiben path-basiert, z. B. `[Route("getPickup/{name}")]`. +- GET-Parameter mit `[FromUri]` markieren. +- Zusaetzlich einen kleinen zentralen Query-Fallback verwenden, weil in 26.1 einzelne optionale Queryparameter trotz `[FromUri]` nicht immer in der Methode ankamen. +- Keine doppelten Controller-Methoden fuer alte und neue URL-Formen bauen. +- Die Postman-Collection testet bewusst die alten Client-URLs. + +Beispiel Query-Route: ```csharp -[Route("getDirectLinkF4SD/{eoid}/{type}"), HttpGet] -public async Task getDirectLinkF4SD(Guid eoid, string type) +[Route("getDirectLinkCreateTicket"), HttpGet] +public async Task getDirectLinkCreateTicket( + [FromUri] string sid = "", + [FromUri] string assetname = "") +{ + sid = QueryValue(sid, nameof(sid)); + assetname = QueryValue(assetname, nameof(assetname)); + ... +} ``` -Funktionierende Legacy-URL: +Beispiel Path-Route mit zusaetzlichen Queryparametern: -```text -/m42Services/api/c4itf4sdwebapi/getdirectlinkf4sd/?eoid=&type=user +```csharp +[Route("getPickup/{name}"), HttpGet] +public async Task getPickup( + [FromUri] string name, + [FromUri] EntityEnumerationVisibilityMode mode = EntityEnumerationVisibilityMode.None, + [FromUri] int group = -1) +{ + name = QueryValue(name, nameof(name)); + mode = QueryValue(mode, nameof(mode)); + group = QueryValue(group, nameof(group)); + ... +} ``` -Daraus folgt fuer diese Migration: +Der zentrale Query-Fallback ist bewusst klein und verwendet die strukturierte WebAPI-API statt eigenes URL-Parsen: -- Controller nicht doppeln. -- Keine Query-Helper einbauen. -- Kein `[FromUri]` als Rettungsversuch verwenden, wenn das Matrix42-Binding ohnehin funktioniert. -- Die Postman-Collection testet bewusst die alten Query-Routen, damit Client-Kompatibilitaet erhalten bleibt. -- `PLSLWebServiceOperation.RouteTemplate` darf path-basiert sein, die alten Query-Aufrufe muessen trotzdem getestet werden. +```csharp +private string GetQueryValue(string name) +{ + return Request?.GetQueryNameValuePairs() + .FirstOrDefault(pair => string.Equals(pair.Key, name, StringComparison.OrdinalIgnoreCase)) + .Value; +} + +private string QueryValue(string value, string name) +{ + return GetQueryValue(name) ?? value ?? string.Empty; +} +``` Betroffene alte Testformate: @@ -295,6 +358,7 @@ Betroffene alte Testformate: getTicketList?sid=...&hours=...&queueoption=...&queues=... getDirectLinkCreateTicket?sid=...&assetname=... getDirectLinkF4SD?eoid=...&type=... +getPickup/?mode=...&group=... ``` ## Pickups und Enumerations @@ -452,7 +516,7 @@ Ein `HttpResponseMessage` wurde als DTO serialisiert. Rueckgabe auf direkten Nut {"result":null,"parameters":{}} ``` -Void-Endpoint oder falsch behandelte leere Rueckgabe. Fuer NoContent `StatusCodeResult(HttpStatusCode.NoContent)` nutzen. +Void-Endpoint oder falsch behandelte leere Rueckgabe. Fuer NoContent einen `IHttpActionResult` mit HTTP 204 liefern. ```text Method returned null @@ -468,7 +532,7 @@ Diese Ansaetze haben nicht nachhaltig geholfen und sollen nicht erneut aufgebaut - Immer mehr Module auf Vorrat laden, ohne die konkrete fehlende Registrierung zu kennen. - `HttpResponseMessage` als Datenantwort verwenden. - Query-Parameter per eigenem Helper aus `RequestUri` lesen. -- `[FromUri]` pauschal an alle GET-Parameter setzen. +- Doppelte Controller-Methoden fuer alte Query-URLs und neue Path-URLs bauen. - `JournalService` direkt konstruieren. - NoOp-/Proxy-Abhaengigkeiten fuer Journal-Services erzeugen. - Journal-Historie aus unvollstaendigen Kommentarfeldern nachbauen. @@ -486,12 +550,17 @@ Diese Ansaetze haben nicht nachhaltig geholfen und sollen nicht erneut aufgebaut 8. AssemblyVersion als einzige Package-Versionsquelle verwenden. 9. WebAPI-Rueckgaben auf direkte DTOs/Listen umstellen. 10. `isAlive` auf echten 204 umstellen. -11. Pickups zuerst ueber schlanke Services loesen. -12. Komplexe Matrix42-Services erst bei Bedarf laden. -13. Bei Unity-Fehlern konkrete Implementierung/Registrator suchen. -14. Postman-Collection fuer alte Client-Routen aufbauen. -15. Paket installieren, Service synchronisieren und Smoke-Tests ausfuehren. -16. Erst nach erfolgreicher Kompatibilitaet fachliche Weiterentwicklungen einbringen. +11. Controller-Routen aus der funktionierenden Legacy-Version uebernehmen. +12. GET-Parameter mit `[FromUri]` versehen und fehlende Querywerte zentral ueber `Request.GetQueryNameValuePairs()` nachziehen. +13. Pickups zuerst ueber schlanke Services loesen. +14. Komplexe Matrix42-Services erst bei Bedarf laden. +15. Bei Unity-Fehlern konkrete Implementierung/Registrator suchen. +16. Webservice-Operationen nach erfolgreicher Installation in Matrix42 synchronisieren. +17. Synchronisierte Operationen exportieren und in die Paketdateien mergen, ohne bestehende IDs zu ersetzen. +18. Operation-Dateien sprechend nach Operation benennen und in `install.xml` referenzieren. +19. Postman-Collection fuer alte Client-Routen aufbauen. +20. Paket installieren, Service synchronisieren und Smoke-Tests ausfuehren. +21. Erst nach erfolgreicher Kompatibilitaet fachliche Weiterentwicklungen einbringen. ## Git- und Datei-Hinweise