Aanleiding
De code van de berichtenbox wordt voor een deel automatisch gegenereerd uit de
API-beschrijving: die beschrijving is de bron van waarheid, en een generator maakt
daar de bijbehorende code bij. Die generator krijgt regelmatig een automatische
update.
De laatste update (7.24.0) verandert hoe de generator de webadressen van de API over
de gegenereerde code verdeelt. Het gevolg: het adres waarop een organisatie een
bericht aanlevert, is niet meer bereikbaar. De berichtenbox antwoordt dat de actie
niet is toegestaan, in plaats van het bericht aan te nemen.
De update is daarom tegengehouden; we draaien door op de vorige versie en het
berichtenverkeer werkt gewoon. Het is dus geen storing, maar we kunnen voorlopig
niet mee met nieuwe versies van deze generator — inclusief de verbeteringen en
beveiligingsfixes die daarin zitten.
Effect voor gebruikers
Zolang we op de oude versie blijven, merkt niemand er iets van. Zou de update
ongemerkt doorgevoerd worden, dan kan geen enkele organisatie nog een bericht
aanleveren.
Daarnaast is er een tweede, breder risico gebleken. Toen dit misging bleef de
geautomatiseerde controle die dit had moeten afvangen zes uur hangen in plaats van
te melden dat er iets fout was. Dat is inmiddels begrensd, maar de onderliggende
oorzaak (het systeem wijst een te grote aanlevering af zonder de verbinding netjes
af te ronden) is nog niet opgelost.
Wenselijk gedrag
- De berichtenbox kan updates van de code-generator volgen zonder dat de
bereikbaarheid van de API verandert.
- Een adres dat in de API-beschrijving staat, is ook daadwerkelijk bereikbaar —
ongeacht hoe de generator de code intern indeelt.
- Gaat er toch iets mis in de geautomatiseerde controles, dan blijkt dat binnen
minuten, niet na uren.
Acceptatiecriteria
Technische context
Wat er gebeurt. openapi-generator 7.24.0 bevat upstream-PR
OpenAPITools/openapi-generator#23871
("Fix path shadowing"). De generator kijkt nu of een gemeenschappelijke pad-prefix
routes van een ándere tag zou afvangen; is dat zo, dan vervalt de class-@Path en
dragen de methodes het volledige pad. Bij ons doet /berichten dat: OphaalApi
houdt class-pad /berichten, terwijl AanleverApi en BeheerApi class-pad ""
krijgen met het volledige pad op de methode.
Waarom het breekt. Quarkus REST resolvet eerst op class-basispad.
POST /api/v1/berichten landt in de /berichten-node (OphaalResource), vindt
daar geen POST en geeft 405 — de ""-class (AanleverResource) wordt niet meer
geprobeerd. Zelfde patroon als
quarkusio/quarkus#26496.
Herkenbaar aan het frame ClassRoutingHandler.handle:77.
Al gedaan in PR #147 (commit 92004a8): de /api/v1-prefix stond dubbel
(spec + @Path(ApiInfo.BASE_PATH + ...) in de resource-classes), wat losse dubbele
pad-segmenten opleverde. Die is nu één keer gezet via quarkus.rest.path, en de
resources die een gegenereerde interface implementeren dragen geen eigen @Path
meer. Dat is een verbetering op zichzelf, maar lost de shadowing niet op — daar zit
het probleem een laag dieper.
Uitgesloten. Dat Quarkus de class-@Path van een geïmplementeerde interface
niet zou oppikken: dan was OphaalResource óók niet geregistreerd en had het een
404 gegeven in plaats van 405.
Oplossingsrichtingen.
- Pinnen op 7.23.0 — dependabot-
ignore op 7.24.x, upstream-issue aanmelden bij
openapi-generator of Quarkus. Goedkoop, maar laat ons achter op een oude versie.
useTags=false in de generator-config — levert één interface per pad-root
(BerichtenApi, class-pad /berichten), waarmee de shadowing verdwijnt. Kost
wel dat aanlever/, ophaal/ en beheer/ samen één resource-class moeten
implementeren; dat botst met de functionele package-indeling en raakt beide
services.
- Spec-paden herzien zodat tags geen gedeelde pad-prefix meer hebben — raakt het
publieke contract en is daarmee de duurste optie.
Losstaand van de generator-keuze, uit dezelfde storing:
- Een 405/404 wordt beantwoord zonder de request-body te lezen. De aanlever-test die
25 MiB uploadt bleef daardoor schrijven tot GitHub de job na 6 uur afkapte. Er
staat nu timeout-minutes: 30 op de test-job als vangnet; een socket-/write-timeout
op de REST-assured-configuratie in de testlaag is de eigenlijke fix.
- Een contracttest die elk pad uit de spec daadwerkelijk aanroept zou deze breuk
direct hebben gevangen; de huidige swagger-request-validator-tests valideren
request/response tegen het schema, maar niet de bereikbaarheid van elk pad.
Aanleiding
De code van de berichtenbox wordt voor een deel automatisch gegenereerd uit de
API-beschrijving: die beschrijving is de bron van waarheid, en een generator maakt
daar de bijbehorende code bij. Die generator krijgt regelmatig een automatische
update.
De laatste update (7.24.0) verandert hoe de generator de webadressen van de API over
de gegenereerde code verdeelt. Het gevolg: het adres waarop een organisatie een
bericht aanlevert, is niet meer bereikbaar. De berichtenbox antwoordt dat de actie
niet is toegestaan, in plaats van het bericht aan te nemen.
De update is daarom tegengehouden; we draaien door op de vorige versie en het
berichtenverkeer werkt gewoon. Het is dus geen storing, maar we kunnen voorlopig
niet mee met nieuwe versies van deze generator — inclusief de verbeteringen en
beveiligingsfixes die daarin zitten.
Effect voor gebruikers
Zolang we op de oude versie blijven, merkt niemand er iets van. Zou de update
ongemerkt doorgevoerd worden, dan kan geen enkele organisatie nog een bericht
aanleveren.
Daarnaast is er een tweede, breder risico gebleken. Toen dit misging bleef de
geautomatiseerde controle die dit had moeten afvangen zes uur hangen in plaats van
te melden dat er iets fout was. Dat is inmiddels begrensd, maar de onderliggende
oorzaak (het systeem wijst een te grote aanlevering af zonder de verbinding netjes
af te ronden) is nog niet opgelost.
Wenselijk gedrag
bereikbaarheid van de API verandert.
ongeacht hoe de generator de code intern indeelt.
minuten, niet na uren.
Acceptatiecriteria
actie (aanleveren, opvragen, wijzigen, verwijderen); geen enkele actie wordt
geweigerd omdat de code intern anders is ingedeeld.
beschrijving niet meer bereikbaar is — het mag niet nodig zijn dat een
ontwikkelaar dat handmatig opmerkt.
vastgelegd waarom dat (voorlopig) niet kan en wat daarvoor nodig is.
geautomatiseerde controle kan hierdoor niet meer blijven hangen.
Technische context
Wat er gebeurt.
openapi-generator7.24.0 bevat upstream-PROpenAPITools/openapi-generator#23871
("Fix path shadowing"). De generator kijkt nu of een gemeenschappelijke pad-prefix
routes van een ándere tag zou afvangen; is dat zo, dan vervalt de class-
@Pathendragen de methodes het volledige pad. Bij ons doet
/berichtendat:OphaalApihoudt class-pad
/berichten, terwijlAanleverApienBeheerApiclass-pad""krijgen met het volledige pad op de methode.
Waarom het breekt. Quarkus REST resolvet eerst op class-basispad.
POST /api/v1/berichtenlandt in de/berichten-node (OphaalResource), vindtdaar geen
POSTen geeft 405 — de""-class (AanleverResource) wordt niet meergeprobeerd. Zelfde patroon als
quarkusio/quarkus#26496.
Herkenbaar aan het frame
ClassRoutingHandler.handle:77.Al gedaan in PR #147 (commit
92004a8): de/api/v1-prefix stond dubbel(spec +
@Path(ApiInfo.BASE_PATH + ...)in de resource-classes), wat losse dubbelepad-segmenten opleverde. Die is nu één keer gezet via
quarkus.rest.path, en deresources die een gegenereerde interface implementeren dragen geen eigen
@Pathmeer. Dat is een verbetering op zichzelf, maar lost de shadowing niet op — daar zit
het probleem een laag dieper.
Uitgesloten. Dat Quarkus de class-
@Pathvan een geïmplementeerde interfaceniet zou oppikken: dan was
OphaalResourceóók niet geregistreerd en had het een404 gegeven in plaats van 405.
Oplossingsrichtingen.
ignoreop 7.24.x, upstream-issue aanmelden bijopenapi-generator of Quarkus. Goedkoop, maar laat ons achter op een oude versie.
useTags=falsein de generator-config — levert één interface per pad-root(
BerichtenApi, class-pad/berichten), waarmee de shadowing verdwijnt. Kostwel dat
aanlever/,ophaal/enbeheer/samen één resource-class moetenimplementeren; dat botst met de functionele package-indeling en raakt beide
services.
publieke contract en is daarmee de duurste optie.
Losstaand van de generator-keuze, uit dezelfde storing:
25 MiB uploadt bleef daardoor schrijven tot GitHub de job na 6 uur afkapte. Er
staat nu
timeout-minutes: 30op de test-job als vangnet; een socket-/write-timeoutop de REST-assured-configuratie in de testlaag is de eigenlijke fix.
direct hebben gevangen; de huidige
swagger-request-validator-tests validerenrequest/response tegen het schema, maar niet de bereikbaarheid van elk pad.