AFAS naar een Azure-datawarehouse: koppeling tegenover automatisering
De HR-manager van de groothandel wil het verzuim per vestiging over de afgelopen drie jaar zien. Ook medewerkers die intussen uit dienst zijn, moeten meetellen. Het personeelssysteem is AFAS, met 40 GetConnectors. Een koppeling die de data ophaalt, is in een uur geregeld, maar die geeft alleen de stand van vandaag.
Een datawarehouse begint pas daarna. Het moet weten welke velden elke GetConnector levert en heeft doeltabellen nodig. Het bewaart historie, haalt 's nachts alleen de wijzigingen op en laat de volgende ochtend zien wat er is gebeurd.
Sanne, de data-engineer van de groothandel, sluit AFAS aan op Yres. Onderweg wordt duidelijk waar de koppeling ophoudt en waar de automatisering begint.
Gepubliceerd: · Laatst bijgewerkt: · Door Daniel Sanders, architect van Yres en oprichter van Plainwater
Wat is een koppeling met AFAS?
Een koppeling met AFAS haalt data op uit een GetConnector: een vooraf gedefinieerde set velden die je via het web kunt opvragen. Elk gereedschap dat een webadres kan aanroepen, kan dat.
De groothandel doet de personeelsadministratie in AFAS. Medewerkers, contracten, verzuim, salarisschalen en afdelingen vormen samen 40 onderwerpen. De HR-manager wil die in rapporten zien naast de omzet uit het boekhoudpakket. Het aansluiten gaat in drie stappen:
- App connector. De AFAS-beheerder maakt in AFAS een App connector aan en hangt daar de 40 GetConnectors onder die Yres mag lezen. AFAS geeft daar een client-id en een geheim bij.
- Bron toevoegen. Sanne voegt in het beheerscherm van Yres een bron toe. Het formulier vraagt het webadres van de AFAS-omgeving, de client-id en het geheim. Die laatste twee gaan naar de sleutelkluis in de eigen Azure-omgeving van de groothandel. Het beheerscherm zelf houdt geen geheimen vast.
- Toegangssleutel. Vóór elke laadactie haalt Yres zelf een kortlopende toegangssleutel op bij AFAS. Die is ongeveer een uur geldig en wordt tijdens het laden per portie opnieuw opgevraagd als dat nodig is. De registratie daarvoor maakt Yres de eerste keer zelf aan, dus niemand plakt of vernieuwt een token.
AFAS beëindigt het klassieke token op 31 augustus 2027 en raadt deze manier aan voor verkeer van server naar server. AFAS is via internet bereikbaar. Er hoeft dus geen aparte verbindingsmachine in het netwerk van de groothandel te staan.
Dat is de koppeling: een uur werk, inclusief koffie. Elk gereedschap dat een webadres kan aanroepen, heeft binnen datzelfde uur data uit een GetConnector. Dat geldt voor een rapportagetool en voor een script van 10 regels. Wie 'een koppeling met AFAS' belooft, belooft dit. Wat daarna nodig is om van 40 GetConnectors een datawarehouse te maken, volgt hieronder.
Wat Yres uit AFAS leest voordat er data stroomt
Voordat de eerste rij medewerkers binnenkomt, moet het datawarehouse weten hoe die rij eruitziet. Welke velden levert de GetConnector met medewerkers? Welk type hebben ze, hoe lang is een tekstveld en hoeveel decimalen heeft een bedrag? Zonder dat antwoord kun je geen doeltabel maken. Sanne zou het per GetConnector kunnen opzoeken en overtypen, 40 keer.
Yres leest het zelf uit AFAS. Na het aanmaken van de bron start Sanne vanuit het beheerscherm het verversen van de metadata. Daarna gebeurt dit:
- De lijst. Yres vraagt AFAS om de lijst van alle GetConnectors onder de App connector.
- De velden. Per GetConnector vraagt Yres de veldbeschrijving op: naam, type, lengte, decimalen en de volgorde van de velden.
- Omwisselen. De beschrijving landt per GetConnector in het woordenboek van Yres. Het oude deel wordt klaargezet, de verse beschrijving komt binnen en dan wisselt Yres dat ene deel in één keer om. Wie intussen het woordenboek leest, ziet nooit een half ververste GetConnector.
- Opruimen. Een GetConnector die de AFAS-beheerder heeft verwijderd, verdwijnt na afloop uit het woordenboek.
- Vergelijken. Yres vergelijkt het verse woordenboek met de tabellen die al bestaan. De verschillen zijn daarna zichtbaar in het beheerscherm.
Eén ding vertelt AFAS niet: welk veld de sleutel is. De veldbeschrijving van een GetConnector zegt niets over uniciteit. Yres legt elk veld daarom vast als mogelijk leeg en zonder sleutelmarkering. De sleutel kiest Sanne zelf, per tabel, in de wizard waarmee ze een GetConnector als tabel toevoegt. Yres doet een voorspelling die ze kan overnemen, of ze vinkt zelf velden aan. Voor medewerkers is dat het medewerkernummer, voor contracten het medewerkernummer plus de ingangsdatum en voor verzuim het verzuimnummer.
In dezelfde wizard kiest ze welke velden meetellen als wijziging, de laadwijze en de kolom met de wijzigingsdatum. Uit het woordenboek en die keuzes maakt Yres per GetConnector twee tabellen aan: de landingszone en de historietabel. De historietabel krijgt vaste kolommen voor begindatum, einddatum en de twee vingerafdrukken uit ons artikel over historie bijhouden bij honderden tabellen.
Elke nacht: porties, historie en de delta op wijzigingsdatum
De eerste keer wordt alles geladen. Om 3.00 uur 's nachts begint de laadronde, in deze volgorde:
- Plannen. De orkestratie van Yres leest uit de metadata welke tabellen aan de beurt zijn. Elke AFAS-tabel gaat naar de pijplijn voor AFAS.
- Klaarmaken. De pijplijn maakt de landingszone leeg en leest uit het woordenboek welk veld uit de GetConnector in welke kolom landt.
- Ophalen. AFAS levert per aanroep een portie rijen. De pijplijn vraagt steeds de volgende portie, met de portiegrootte die per tabel is ingesteld. Geeft AFAS een lege portie terug, dan is de tabel compleet.
- Vergelijken. De motor vergelijkt elke rij uit de landingszone met de actuele versie in de historietabel, zoals bij elke andere bron. Een nieuw medewerkernummer wordt toegevoegd. Bij hetzelfde nummer met andere inhoud wordt de oude versie afgesloten en komt er een nieuwe bij. Bij dezelfde inhoud gebeurt er niets.
Mislukt één portie, dan stopt de lus netjes. De fout staat met de naam van de stap in het logboek en de tabel staat als mislukt in het monitoringscherm. Van elke laadactie toont het monitoringscherm per tabel de status, het aantal rijen en de duur.
De tweede nacht wordt interessant. De GetConnector met medewerkers heeft een veld met de datum waarop een record voor het laatst is gewijzigd. Sanne heeft dat veld als wijzigingskolom gekozen en de laadwijze op alleen wijzigingen gezet. Yres bouwt dan per nacht een filter voor AFAS: geef me alle rijen waarvan de wijzigingsdatum op of na het watermerk ligt. Het watermerk is de hoogste wijzigingsdatum die bij het vorige laden is gezien. Is de wijzigingskolom een datum, dan zet Yres het watermerk in het datumformaat dat AFAS verwacht. De allereerste keer staat het watermerk op 1 januari 1900, zodat alles meekomt. Yres vraagt AFAS ook om de rijen op sleutel te sorteren. Zo overlappen de porties van één laadactie elkaar niet en slaan ze ook niets over.
Daar komen twee verfijningen bij:
- Overlap. Sanne kan een overlap instellen, bijvoorbeeld één dag. Yres vraagt dan om alles vanaf het watermerk min een dag. Een record dat laat is bijgewerkt, komt zo alsnog mee. Dubbele versies ontstaan niet, want rijen met gelijke inhoud krijgen geen nieuwe versie.
- Twee wijzigingskolommen. Een GetConnector kan twee datumvelden hebben die samen 'laatst gewijzigd' betekenen, zoals een aanmaakdatum naast een wijzigingsdatum. Yres accepteert voor AFAS twee wijzigingskolommen van hetzelfde type. Het filter wordt dan: de ene datum op of na het watermerk, of de andere.
Het watermerk schuift pas op als het laden helemaal is afgerond, inclusief de verwerking in de historietabel. Mislukt een portie halverwege, dan blijft het watermerk op de vorige nacht staan en meldt het monitoringscherm dat. De volgende nacht haalt Yres het verschil opnieuw op, zonder dat Sanne iets hoeft te herstellen.
| Stap | Een koppeling met AFAS | Yres |
|---|---|---|
| Verbinden | Webadres, client-id en geheim in handen van wie de aanroep doet. Zelf de toegangssleutel ophalen en verversen | Webadres, client-id en geheim in de wizard, de geheimen in de sleutelkluis van je eigen Azure-omgeving. Yres haalt de kortlopende toegangssleutel zelf op |
| Weten welke velden er zijn | Per GetConnector opzoeken en overtypen | Veldbeschrijving van elke GetConnector in het woordenboek, per GetConnector in één keer omgewisseld |
| Doeltabellen | Zelf ontwerpen, 40 keer | Landingszone en historietabel gegenereerd uit het woordenboek |
| Historie | Geen, de data is de stand van de laatste aanroep | Versies per rij met begin- en einddatum, dezelfde motor als voor alle andere bronnen |
| Alleen de wijzigingen | Elke keer de hele GetConnector | Filter op de wijzigingsdatum vanaf het watermerk, met overlap en een tweede kolom als dat nodig is |
| Porties | Zelf de lus bouwen | Portie voor portie tot AFAS een lege portie geeft. Een mislukte portie staat in het logboek |
| Monitoring | Per aanroep, als iemand het logt | Per tabel: status, rijen, duur en of het watermerk is opgeschoven |
Wat gebeurt er als AFAS verandert?
Verandert een GetConnector, dan ververs je de metadata en werk je de tabellen bij vanuit het woordenboek. Bij AFAS is dat bijwerken een handeling die je zelf start.
Een GetConnector is geen vaste tabel. De AFAS-beheerder kan er een veld aan toevoegen, een veld weghalen of de hele GetConnector vervangen. In februari voegt hij aan de GetConnector met contracten het veld voor de reiskostenvergoeding toe. Sanne ververst de metadata van AFAS in het beheerscherm. Yres leest de veldbeschrijving opnieuw, wisselt het deel voor contracten om en vergelijkt het woordenboek met de bestaande tabellen. Het nieuwe veld verschijnt als verschil. Sanne laat de tabellen bijwerken. Bij de volgende laadactie loopt het veld mee in de vergelijking.
Een veld dat verdwijnt of van naam verandert, is lastiger. Voor het datawarehouse is een hernoemd veld een veld dat weg is plus een veld dat nieuw is. Wat Yres daarmee doet, staat in ons artikel over schema drift.
Dan de aanmelding. De kortlopende toegangssleutel verloopt elk uur, maar Sanne merkt daar niets van. Yres haalt hem zelf opnieuw op. Alleen het geheim van de App connector kan verlopen of worden ingetrokken. Trekt de AFAS-beheerder het geheim in, dan geeft AFAS geen toegangssleutel meer. Het laden van elke AFAS-tabel mislukt die nacht dan al bij het ophalen van de sleutel. Het monitoringscherm toont 40 mislukte tabellen met dezelfde stap. Het watermerk van elke tabel blijft staan, dus na een nieuw geheim haalt de volgende nacht alles in.
Wanneer is een koppeling genoeg?
Een koppeling is genoeg als je één bron hebt en alleen de stand van vandaag wilt zien. Drie gevallen uit de groothandel laten het verschil zien.
Het aantal medewerkers van vandaag. De HR-manager wil een scherm met het aantal medewerkers per afdeling. Dat is één bron en de actuele stand, zonder vergelijking met vorig jaar. Een rapportagetool rechtstreeks op de GetConnector volstaat dan. Yres hoeft daar niet tussen.
Verzuim over drie jaar. De directie wil het verzuimpercentage per vestiging over de afgelopen drie jaar. Medewerkers die intussen uit dienst zijn, tellen mee, met de afdeling waar ze toen werkten. Dat vraagt om versies: wie werkte wanneer waar. Een GetConnector geeft de stand van nu. De historietabel van Yres geeft ook de stand van toen.
Uren uit drie bronnen. De planner wil de contracturen uit AFAS naast de ingeplande uren uit het planningspakket en de verkochte uren uit het boekhoudpakket. Dat zijn drie bronnen met één medewerkernummer. Hier wordt een koppeling per bron een datawarehouse. De drie tabellen staan in dezelfde database, onder dezelfde historieregels, geladen door dezelfde motor.
Er speelt ook iets wat je niet in een rapport ziet. Een rapportagetool die rechtstreeks op AFAS staat, vraagt bij elke verversing de hele GetConnector op. Tien rapporten die elk uur verversen, zijn samen 240 aanroepen per dag per GetConnector. Yres vraagt zo vaak als de trigger is ingesteld, bij de groothandel eenmaal per nacht. Met een wijzigingskolom vraagt het bovendien alleen om de rijen van die dag. AFAS merkt er dan weinig van.
Waar het ophoudt
- Yres leest wat een GetConnector levert. Welke velden erin zitten, bepaalt de AFAS-beheerder
- Alleen wijzigingen ophalen werkt alleen als de GetConnector een wijzigingsdatum bevat. Zonder dat veld laadt Yres de GetConnector elke keer volledig, portie voor portie
- De sleutel van een GetConnector staat niet in AFAS. Die kies je zelf, per tabel
Veelgestelde vragen
Is 'een koppeling met AFAS' hetzelfde als AFAS in een datawarehouse?
Nee. Een koppeling is het vertrekpunt dat elk gereedschap heeft. Yres gebruikt dezelfde koppeling en doet de rest uit de metadata: doeltabellen, historie, alleen de wijzigingen en monitoring per tabel.
AFAS heeft toch een eigen koppeling voor rapportages en Power BI. Waarom dan een datawarehouse?
Voor één bron en de cijfers van vandaag is dat genoeg. Een datawarehouse voegt historie toe, combineert AFAS met andere bronnen op één sleutel en vraagt AFAS maar één keer per nacht om de wijzigingen. Power BI blijft daarbij je rapportagelaag, alleen leest het dan uit het datawarehouse. Heb je geen historie of combinatie nodig, dan is Yres hier niet de oplossing.
Haalt Yres elke nacht alle 40 GetConnectors volledig op?
Alleen als je dat per tabel zo instelt. Een GetConnector met een wijzigingsdatum laad je met alleen wijzigingen. Een GetConnector zonder zo'n veld laadt Yres volledig. Ook dan krijgt alleen een rij die echt veranderd is een nieuwe versie.
Wat gebeurt er als het geheim van de App connector verloopt?
Dan krijgt Yres geen toegangssleutel meer en mislukt die nacht elke AFAS-tabel bij dezelfde stap. Leg daarom bij het aanmaken van de bron de vervaldatum van het geheim vast. Na een nieuw geheim haalt de volgende nacht het verschil vanzelf in.
Praat met een data-architect
In 30 minuten kijkt een data-architect met je mee naar je huidige dataomgeving en waar het nu wringt.
Plan een gesprek →
