Oversikt
Ved innføring av DFØ-SAP har vi fått på plass en ny integrasjon for oppdatering av ansatt-informasjon.
Integrasjonen består av bl.a.:
- Modul
- Cerebrum.modules.hr_import
- Cerebrum.modules.tasks
- Cerebrum.modules.no.dfo
- Cerebrum.modules.no.uio.dfo
- Cerebrum.modules.no.uio.hr_import
- Cerebrum.utils.backoff
- Script
- contrib/hr-import/create-task.py (manuell køing -> ordinær import)
- contrib/hr-import/manual-import.py (manuell import)
- contrib/hr-import/list-tasks.py (vise kø for enkeltimport)
- contrib/tasks/search-tasks.py (søke / vise tasks i kø)
- contrib/hr-import/process-tasks.py (kø-prosessering / import)
- consumers/consume-tasks.py (meldingskø -> oppgavekø)
- Config
- <path/to/etc>/cerebrum/config/hr-import-consume.yml (meldingsconsumer)
- <path/to/etc>/cerebrum/config/hr-import-assignments.yml (stillingsimport)
- <path/to/etc>/cerebrum/config/hr-import-employees.yml (ansattimport)
- <path/to/etc>/cerebrum/config/hr-import-client.yml (api-klient)
- <path/to/etc>/cerebrum/config/hr-import-mapper.yml (forretningslogikk)
- Jobber
- hr_import_consume (meldingsprosessering)
- hr_import_employees (import av ansatte)
- hr_import_assignments (oppdatering ved endring på stilling)
HR-importen er mer komplisert enn tidligere integrasjon med SAPUiO - av flere grunner:
- Mer omfattende integrasjon - utelukkende meldingsbasert. Ingenting ser lenger på sap2bas.xml
- Mer robust integrasjon - DFØ-integrasjonen trenger bedre feilhåndtering enn vår gamle SAPUiO-integrasjon.
- DFØ endrer på en del ting (ny ou-identifikator, forretningslogikk rundt stillinger, flere start- og sluttdatoer å forholde seg til, sammensatte stillinger, mindre informasjon som vi må supplere med fra andre systemer, etc...)
- Mer generell integrasjon:
- Vi trengte en ny implementasjon som kunne fungere med både SAPUiO og DFØ (i overgang)
- Vi trengte en implementasjon som også kan uvides og tilpasses andre institusjoner
- Vi trengte en implementasjon som kunne tilpasses mer underveis (fordi DFØ-SAP sine API-er ikke var ferdige/etablerte når vi satte i gang).
Tasks
Tasks er oppgaver som skal utføres senere. I hr-importen er en oppgave typisk å håndtere en endring. I fremtiden kan vi tenke oss at f.eks. bofhd-requests kan re-implementeres som tasks, eller at andre integrasjoner også benytter seg av task-køer for håndtere meldinger.
- queue
- Hvilken kø oppgaven hører hjemme i. Alle tasks i en enkelt kø håndteres av samme prosess (typisk samme script, jobb, etc...). I hr-import har vi to køer: dfo-employee (ansatt), dfo-assignment (stilling)
- sub
- Sub-queue, sub-key - brukes for å tagge en task av forskjellige typer. Eksempel: I hr-importen bruker vi en blank sub for orinære meldinger, og sub=nbf for meldinger som har en not before-dato i fremtid. Dette lar oss lagre to tasks for et og samme ansattnummer.
- key
- Unik nøkkel for oppgave. I hr-import brukes referansen til objektet som er endret (ansattnummer, stillingsnummer)
- nbf
- Not before - tasks behandles kun etter at dette tidspunktet har passert. Ordinære meldinger får satt nbf=now()
- attempts
- En teller som viser hvor mange forsøk som er blitt gjort på å utføre oppgaven.
Feilhåndtering
Dersom en oppgave (f.eks. import av ansattnummer 123) feiler, så vil attempts økes med en, og nbf bli satt til en tid i fremtiden. Hvor langt frem i tid nbf skyves er avhengig av hvor mange forsøk vi har gjort.
Dette følger en trunkert eksponensiell binær backoff-algoritme, med start på 3 ¾ minutt, og trunkering på 12 timer:
- Forsøk 1: vente 3 ¾ minutt
- Forsøk 2: vente 7 ½ minutt
- Forsøk 3: vente 15 minutter
- Forsøk 4: vente 30 minutter
- Forsøk 5: vente 1 time
- Forsøk 6: vente 2 timer
- Forsøk 7: vente 4 timer
- Forsøk 8: vente 8 timer
- Forsøk 9: vente 12 timer
- Forsøk N: vente 12 timer
I hr-importen er maks antall forsøk satt til ~20, så siste forsøk vil skje omtrent 7 dager etter første forsøk.
Overordnet flyt
Meldinger
Meldingskonsument mottar meldinger og oversetter disse til tasks i vår nye, interne task-kø.
- jobb: hr_import_consume
- script: consume-tasks.py
- config: hr-import-consume.yml
Jobben er generell nok til å håndtere alle meldinger fra alle systemer som skal oversette fra meldinger til tasks - ikke bare DFØ/hr-import.
Konfigurasjonen peker på en funksjon som oversetter melding til 0, 1 eller flere oppgaver som legges inn i køen.
Håndtering av oppgaver
Et eget script sørger for å håndtere oppgaver knyttet til hr-importen:
- script: hr-import/process-tasks.py
Scriptet henter ut en liste over oppgaver hvor:
- nbf har passert/er i fortid
- attempts er mindre enn 20
... og behandler dem i rekkefølge. Rollback/commit gjøres etter hver oppgave, så endringer kan bli utført selv om scriptet ikke fullfører som det skal.
Siden vi får to typer meldinger (endring på ansatt, endring på stilling), som vi oversetter til oppgaver i to separate køer, så har vi også to separate jobber som håndterer oppgaver:
Endring på ansatt
- kø: dfo-employee
- jobb: hr_import_employee
- config: hr-import-employee.yml
Utfører import av ansatt.
Endring på stilling
- kø: dfo-assignment
- jobb: hr_import_assignment
- config: hr-import-assignment.yml
- oppgaver: Cerebrum.modules.no.dfo.tasks.AssignmentTasks
Henter alle ansatte på stilling, og lager en oppgave per ansatt for senere oppdatering. Selve importen vil utføres neste gang hr_import_employee kjører.
Felles
Hver av importene trenger bl.a. en klient for å kommunisere med DFØ:
Hvilken klient som brukes, og hvilken konfigurasjonsfil som benyttes settes i hr-import-employee.yml/hr-import-assignment.yml, men vil stort sett være:
- hr-import-client.yml (api-klient, url-er og api-nøkler)
- hr-import-mapper.yml (forretningslogikk)
Fremtidige endringer
Ved import av person, så hender det at vi _ser_ at personen har en stilling som ikke er gyldig enda, eller en stilling som skal avsluttes om kort tid.
Hvis dette oppdages, så vil vi ta den førtskommende datoen hvor en endring skal inntreffe, og legge inn en task i køen.
F.eks.:
- Stilling A: 2010-01-01 - 2025-12-31
- Stilling B: 2023-01-01 - 2030-12-31
Dersom vi gjør en import av denne ansatte på datoen 2022-06-15, så ser vi at neste endring skjer om seks måneder (stilling B starter). Vi lager derfor en task om dette. Når denne datoen inntreffer, vil importen oppdage at neste endring er 2025-12-31 (stilling A avsluttes), og legge inn en task om dette.
De fleste ansatte vil derfor ofte ha en slik fremtidig endring liggende i køen.
Verktøy
- Manuell import
Scriptet contrib/hr-import/manual-import.py gjør en umiddelbar, manuell oppdatering fra DFØ, uten å blande inn oppgavekøen.
F.eks.:
python hr-import/manual-import.py \ --config /cerebrum/etc/cerebrum/config/hr-import-employee.yml \ --commit \ 01234567
- Manuell oppgave
Scriptet contrib/hr-import/create-task.py legger til en oppgave i oppgave-køen. Den ansatte vil da automatisk oppdateres neste gang jobben hr_import_employee (eller hr_import_assingment hvis man køer en stilling) kjører.
F.eks.:
python hr-import/create-task.py \ --config /cerebrum/etc/cerebrum/config/hr-import-employee.yml \ --commit \ 01234567 python hr-import/create-task.py \ --config /cerebrum/etc/cerebrum/config/hr-import-assignment.yml \ --commit \ 30001234
- Liste oppgaver for en gitt import
Scriptet hr-import/list-tasks.py leser import-config og lister ut tasks som vil kjøre ved neste kjøring av jobben.
F.eks.:
python hr-import/list-tasks.py \ --config /cerebrum/etc/cerebrum/config/hr-import-employee.yml
- Søke etter oppgaver
Scriptet tasks/search-tasks.py er et generelt verktøy for å inspisere oppgavekøen.
F.eks.:
python contrib/tasks/search-tasks.py --help python contrib/tasks/search-tasks.py \ --queue dfo-employee \ --min-attempts 20 \ --limit 10 \ --show-reason