MAGDA gebruik


Inleiding

Deze pagina legt uit hoe je een MAGDA-connector concreet aanspreekt, hoe je het antwoord kan ontleden, en hoe je fouten kan afhandelen. Deze uitleg is generiek. Ze geldt in essentie voor elke MAGDA-connector (Persoon, Gezin, Kadaster, enzovoort). Voor connector-specifieke details (functies, parameters, foutcodes) raadpleeg je de individuele pagina’s.

Strategie

Een MAGDA-connector aanspreken kan op drie verschillende manieren.

  • Eerst en vooral vanuit de BPMN-workflow via een expressie. Dit is de typische configurator-aanpak. Aanpassingen vereisen geen build & deploy en kunnen daardoor snel doorgevoerd worden. De keerzijde van deze wendbare strategie is dat de mogelijkheden beperkt blijven tot het opvragen en doorgeven van enkelvoudige waardes.

  • Ten tweede vanuit de BPMN-workflow via een script. Deze aanpak blijft configurator-gericht, maar biedt het voordeel dat het iets meer complexiteit kan opvangen.

  • Ten derde vanuit Java-code. Dit vereist de tussenkomst van een developer, alsook van een build & deploy van je applicatie voor elke wijziging. Tegenover deze nadelen staat dan weer het voordeel van meer controle en complexiteit.

Strategie

Use case

Beperkingen

BPMN-expressie (JUEL)

Eén waarde rechtstreeks doorgeven of uitlezen.

Enkel enkelvoudige waarden; geen lussen, geen foutafhandeling.

BPMN-script (JavaScript, Script Task)

Eenvoudige logica, lussen, en via Java-interop zelfs een BpmnError opwerpen.

Technisch mogelijk, maar geen compiler-controle, moeilijk te testen, verspreid over BPMN-bestanden, wordt afgeraden voor complexe foutafhandeling.

Java-code (JavaDelegate of aparte service)

Volledige controle: foutafhandeling per foutcode, complexe ontleding, wegschrijven naar meerdere plekken.

Vereist een developer, build & deploy voor elke wijziging.

Aanspreekpatronen

Vanuit BPMN-workflow via expressie

Je roept de connector aan vanuit een service-taak in je BPMN-proces, via een Camunda-expressie. De naam vóór het punt (bv. magda, mds) verwijst naar de naam van de Spring-bean die de connector implementeert.

${magda.geefPersoon(String identifier, String dossierId)}

Voor sommige connectoren (bv. MDS, zie MAGDA Document Service (MDS)) geef je geen losse parameters mee, maar het volledige execution-object. De eigenlijke configuratie gebeurt dan via inputparameters op de servicetaak zelf, ingesteld via een Skryv Studio service taak template.

${mds.publishMessage(execution)}

Vanuit JAVA-code

Een connector kan ook rechtstreeks vanuit eigen Java-code aangesproken worden, via dependency injection. Dit is vooral relevant voor maatwerkcode binnen een specifieke Skryv-applicatie.

Java
@RequiredArgsConstructor
public class MyOwnService {
    private final MagdaCamundaConnector magda;

    public void doSomething(String identifier, String dossierId) {
        GeefPersoonResponse response = magda.geefPersoon(identifier, dossierId);
        // verwerk het antwoord
    }
}

Ontvangen antwoord

Op de specifieke MAGDA-connectorpagina’s vind je per functie telkens een gepseudonimiseerd voorbeeld van een antwoord. De structuur van het antwoord verschilt grondig afhankelijk van het communicatieprotocol van de MAGDA-dienst (SOAP of REST). De antwoorden worden ofwel opgeslagen in een procesvariabele ofwel rechtstreeks opgevangen als retourwaarde in je Java-code.

Opgelet: het antwoord dat je terugkrijgt, kan bewust ingekort zijn. MAGDA beperkt het teruggestuurde object tot enkel die eigenschappen waarvoor jouw applicatie specifieke machtigingen heeft gekregen tijdens het onboardingproces. Velden die technisch beschikbaar zijn in de MAGDA-specificatie, zijn daardoor mogelijk niet aanwezig in de respons van jouw applicatie. Neem bij twijfel contact op met de MAGDA Service Desk of raadpleeg de afspraken die bij de onboarding werden gemaakt.

SOAP-gebaseerde diensten

Het antwoord is een gestructureerd Java-object, JAXB-gegenereerd op basis van de MAGDA-XSD. Elk antwoord volgt in essentie dezelfde envelop-structuur:

Repliek
 └─ Antwoorden
     └─ Antwoord
         ├─ Referte
         ├─ Inhoud          ← de eigenlijke gegevens
         └─ Uitzonderingen  ← eventuele fouten (zie Fouthandeling)

Bij sommige diensten (zoals Repertorium) kan Repliek zelf ook al een Uitzonderingen-blok bevatten. Dat gaat dan over fouten die optreden vóór de vraag zelf verwerkt wordt.

REST-gebaseerde diensten

Het antwoord is een JSON-object, rechtstreeks naar een Java-object gemapt (Jackson). Er is geen gemeenschappelijke envelop-structuur zoals bij SOAP. De vorm verschilt per dienst. Sommige diensten (bv. MDS publishMessage) gebruiken een eigen status-veld (SUCCESS/WARNING/ERROR) in plaats van een exceptie bij een fout; andere (bv. de eBox-consentcheck) geven simpelweg het gevraagde object terug, zonder apart statusveld. Onderstaand voorbeeld toont de structuur van een eBox-consentcheck.

JSON
{
    "eboxId": {
        "eboxType": "CITIZEN",
        "eboxIdValue": "850102XXX45"
    },
    "exclusivelyEbox": true
}

Antwoordstructuur ontleden

Ontleden binnen BPMN-expressie

Zit het resultaat in een procesvariabele (via camunda:resultVariable), dan lees je dat verder uit met puntnotatie in kleine letters (geen get/hoofdletters/haakjes zoals in Java-code). De expressie-taal (JUEL) of scripttaal (JavaScript) roept dan automatisch de bijhorende getter aan, op basis van JavaBean-conventies.

${geefPersoon.repliek.antwoorden.antwoord.inhoud.persoon.naam.achternamen.achternaam[0].value}

Merk op:

  • geefPersoon is hier de naam van de procesvariabele, niet de bean-naam (magda) zelf.

  • De structuur (.repliek.antwoorden.antwoord.inhoud...) is identiek aan de Java-toegang, enkel zonder get().

  • Gebruik vierkante haken ([0]) enkel voor elementen die effectief een lijst zijn (zoals Achternamen, dat meerdere achternamen kan bevatten). Antwoord zelf is steeds een enkelvoudig object en wordt nooit geïndexeerd.

Ontleden binnen een BPMN-script

In een script task (JavaScript, via de Nashorn-engine) heb je meer mogelijkheden dan in een eenvoudige expressie: je kan lussen en voorwaarden schrijven, en via Java-interop zelfs Java-klassen aanspreken, inclusief het opwerpen van een BpmnError.

JavaScript
// Script Task, scriptformaat: JavaScript
var BpmnError = Java.type('org.camunda.bpm.engine.delegate.BpmnError');

var response = geefPersoon; // procesvariabele, resultaat van de service-taak

if (response.repliek == null || response.repliek.antwoorden == null) {
    throw new BpmnError("MAGDA_GEEN_ANTWOORD");
}

// Uitzonderingen op Antwoord-niveau doorlopen
var antwoord = response.repliek.antwoorden.antwoord;
if (antwoord.uitzonderingen != null) {
    var uitzonderingen = antwoord.uitzonderingen.uitzondering;
    for (var i = 0; i < uitzonderingen.size(); i++) {
        var code = uitzonderingen.get(i).identificatie;
        if (code === "30001" || code === "30003") {
            throw new BpmnError("MAGDA_PERSOON_NIET_GEVONDEN", uitzonderingen.get(i).diagnose);
        }
    }
}

// Geen blokkerende fout: waarde uitlezen en als procesvariabele wegschrijven
execution.setVariable("achternaam", antwoord.inhoud.persoon.naam.achternamen.achternaam.get(0).value);

Zodra je dit soort logica nodig hebt, overweeg dan of dit niet beter in een Java-klasse thuishoort. Een script task is lastiger te testen en te herzien dan een gewone Java-methode met unit tests.

Ontleden binnen Java-code

SOAP-gebaseerde diensten

Zoals eerder aangegeven volgt elk SOAP-antwoord dezelfde envelop: Repliek → Antwoorden → Antwoord → Inhoud.

Concreet in Java:

GeefPersoonResponse response = magda.geefPersoon(identifier, dossierId);

// Stap 1: is er een Repliek, en zit er al een Uitzondering op dat niveau? (zie Fouthandeling)
if (response.getRepliek() == null) {
    throw new BpmnError("MAGDA_LEEG_ANTWOORD");
}

// Stap 2: is er een Antwoorden/Antwoord-blok?
if (response.getRepliek().getAntwoorden() == null) {
    throw new BpmnError("MAGDA_GEEN_ANTWOORD");
}

// Stap 3: pas dan de Inhoud uitlezen — Antwoord is een ENKELVOUDIG object, geen lijst
String insz = response.getRepliek().getAntwoorden().getAntwoord()
    .getInhoud().getPersoon().getINSZ();

REST-gebaseerde diensten

Rechtstreekse toegang tot het object.

Concreet in Java:

EboxInfo info = mds.checkEboxActiveCitizen(rrn);

boolean heeftActieveEbox = info.getExclusivelyEbox();
String opgevraagdType = info.getEboxId().getEboxType();

Bij diensten met een eigen status-veld (bv. MDS publishMessage) ontleed je eerst dat veld, vóór je de rest van het object gebruikt:

MdsPublishMessageResponse response = mds.publishMessage(execution);

if ("ERROR".equals(response.getStatus())) {
    throw new BpmnError("MDS_PUBLICATIE_MISLUKT", response.getErrorMessage());
}

String eboxMessageId = response.getEboxMessageId();

Error-handling

Foutpatroon bij SOAP-gebaseerde diensten

Het antwoord bevat een Uitzonderingen-blok. Een Uitzondering bevat:

  • Identificatie (de foutcode).

  • Type (FOUT/WAARSCHUWING/INFORMATIE).

  • Oorsprong (MAGDA of de achterliggende bron), Diagnose (leesbare beschrijving).

  • Annotaties (niet altijd aanwezig, extra context, bv. een oud/nieuw INSZ bij een vervangen persoonsnummer).

Welke foutcodes precies relevant zijn, verschilt per MAGDA-dienst. Raadpleeg hiertoe de Error-handling-sectie van de specifieke connectorpagina die je gebruikt.

Foutpatronen bij REST-gebaseerde diensten

Hier is er geen Uitzondering-structuur. Twee patronen komen voor:

  • HTTP-statuscodes (400/401/404/500/502/503/504) met een RFC 7807-achtige foutbody (title/status/detail/instance). De onderliggende technische connector zet dit meestal om naar een generieke exceptie (bv. MDSException), die je zelf kan opvangen en omzetten naar een BpmnError.

  • Een statusveld in een overigens geldig antwoord (bv. MdsPublishMessageResponse.status = ERROR). Hier gebeurt er geen exceptie; je controleert dit veld zelf en gooit desgewenst een BpmnError.

Daarnaast kan een X-Magda-Exceptions-header een aparte, niet-blokkerende waarschuwing meegeven (bv. een consent-probleem). Deze verdient meestal enkel een log-actie.

Foutafhandeling

Fouten kan je op drie verschillende manieren aanpakken.

Aanpak

Wanneer?

Gevolg voor het proces?

Niets doen (enkel loggen, sentinel-waarde zetten)

De uitzondering is een verwacht, niet-blokkerend scenario (bv. ‘geen historiek gekend’).

Proces loopt normaal door; geen incident, geen vertakking.

BpmnError opwerpen

Je wil een gecontroleerde vertakking in de BPMN-flow.

Proces vertakt via een error boundary event naar een alternatief pad.

Niet-omgezette exceptie (bv. bij een technisch probleem)

Onverwachte, technische fout die manuele tussenkomst vereist.

Camunda-incident; een beheerder moet via Cockpit ingrijpen.

Voorbeeld 1: niets doen (enkel loggen)

Via Java-code:

if (!uitzonderingen.isEmpty()) {
    for (UitzonderingType u : uitzonderingen) {
        switch (u.getType()) {
            case "INFORMATIE" -> LOGGER.info(...);
            case "WAARSCHUWING" -> LOGGER.warn(...);
            default -> LOGGER.error(...); // FOUT
        }
        // eventueel bewaren in een eigen document voor latere raadpleging
    }
    return sentinelValue; // proces loopt normaal door
}

Voorbeeld 2: BPMN-error

Via Java-code:

for (UitzonderingType u : uitzonderingen) {
    String code = u.getIdentificatie();
    if ("30001".equals(code) || "30003".equals(code)) {
        throw new BpmnError("MAGDA_NIET_GEVONDEN", u.getDiagnose());
    }
    if ("20002".equals(code)) {
        throw new BpmnError("MAGDA_ONGELDIG_INSZ", u.getDiagnose());
    }
}