eHOKS-backend on jaettu kahteen osaan: virkailija ja oppija. Virkailijan puoli käsittää virkailijan käyttöliittymän rajapinnat ja datan tuontiin tarkoitetut rajapinnat.
Tällä hetkellä sovellus jakaa koodipohjan eri osien välillä ja ainoastaan rajapintojen polut on jaettu palveluittain.
Frontend ks. Github Repository
Katso Leiningenin määrityksistä.
Java 21.
Muut riippuvuudet:
- Podman tai Docker, kehitysympäristön tietokantaa varten
- Ehkä:
psql
, kehitysympäristön tietokannan tutkimiseen - Ehkä:
make
automaatiosääntöjen käyttöön (ks alla) - Ehkä:
curl
jos haluaa käyttää rajapintaa suoraan (esim luoda testidataa), myös jotkin skriptit käyttävät tätä - Ehkä:
jq
joidenkin skriptien toimintaan - Ehkä:
graphviz
tietokantakaavioihin kun tekeemake schemaDoc
Backend pyrkii seuraamaan RESTful periaatteita. Kaikki vastaukset (paitsi no content) sisältävät meta- ja dataobjektit.
Avaimet seuraavat Clojuren notaatiota.
Hakemistossa scripts on paljon erilaisia esimerkkejä siitä, miten eHOKSin rajapintoja käytetään ja miten siitä riippuvaisia palveluita.
Noudatetaan kehittäjien kesken sovittuja koodikäytänteitä.
Repossa on .editorconfig
jonka avulla voit kertoa editorillesi käytettävät
tyylit.
Pystytä ensin tietokanta, testit toimivat aitoa tietokantaa vasten:
make stamps/db-schema
. DynamoDB-testit tarvitsevat myös lokaalin
DynamoDB:n: make stamps/local-ddb-schema
.
Kerran:
lein test
Muutoksista:
lein auto test
Testien kattavuus:
lein with-profile test cloverage
Jos tarvitset enemmän lokiviestejä, muuta rootLogger.level asetustiedostossa.
Staattiset linterit ajetaan:
lein checkall
tämä ajaa Kibit, Bikeshed, Eastwood ja cljfmt kerralla. Jokainen työkalu on ajettavissa myös erikseen:
lein kibit
lein bikeshed
lein eastwood
lein cljfmt check
Ohjelmalle voi antaa parametrina sovelluksen nimen. Nimi on joko ehoks
(oppija) tai ehoks-virkailija
(virkailija). Molemmat sovellukset on
oletuksena valittuna. Lisäksi ohjelma ottaa vastaan parametreina käytettävän
konfiguraatiotiedoston. Ohjelman nimen (NAME
) ja konfiguraatiotiedoston
(CONFIG
) voi antaa myös ympäristömuuttujana.
Oletuskonfiguraatiolla oph-configuration/default.edn
ohjelma ottaa yhteyttä
paikalliseen postgresiin tietokantaan ehoks
. Katso lisää sen pystyttämisestä
kohdassa PostgreSQL.
Tuotantomoodissa:
lein run
Kehitysmoodissa:
lein with-profile +dev run
tai
lein with-profile +dev run ehoks-virkailija
tai
lein trampoline with-profile +dev run ehoks-palaute
Replissä lein with-profiles +dev repl
:
user> (require 'oph.ehoks.dev-server)
user> (def server (oph.ehoks.dev-server/start "ehoks-virkailija" nil))
;; jos oot jo oikeassa nimiavaruudessa, kuten dev-profiili tekee
oph.ehoks.dev-server=> (def server (start "ehoks-virkailija" nil))
Tai omalla konfiguraatiolla:
oph.ehoks.dev-server=> (def server (start "both" "config/custom.edn"))
Nimiavaruudessa oph.ehoks.ehoks-app
ovat ne muuttujat (var), jotka
start
antaa run-jettylle käsittelemään kutsuja. Siksi juuri tämän
nimiavaruuden reload saa Jettyn käsittelemään tulevat kutsut päivitetyllä
handlerilla jos esim. lähdekoodia on muutettu:
oph.ehoks.dev-server=> (require 'oph.ehoks.ehoks-app :reload-all)
Mikäli tämä ei auta (jos esim. kyse on varsinaisen handlerin ulkopuolella tehdyistä muutoksista), serverin voi myös uudelleenluoda (reload toki tarvitaan silti sille nimiavaruudelle, jota on muutettu):
oph.ehoks.dev-server=> (.stop server)
[...]
nil
oph.ehoks.dev-server=> (def server (start "ehoks-oppija" nil))
Ja ohjelman sammuttaminen:
user> (.stop server)
Tietokannan migraatiot voi ajaa komennolla
make stamps/db-schema # tai käsin: lein dbmigrate
Tietokantaan voi viedä myös esimerkkidataa komennolla
make stamps/example-data
Yllä oleva komento ajaa serverin taustalla ja syöttää esimerkkidatat sen kautta. Jos haluat itse ajaa serveriä, tee näin:
make stamps/db-schema
# pystytä serveri tässä
touch stamps/server-running
make stamps/example-data
Tietokannan QA-ympäristön skeemaversio on dokumentoituna osoitteessa
https://db-documentation.testiopintopolku.fi/ehoks/public/index.html .
Samanlaisen dokumentaation voi luoda testiympäristöstä komennolla make schemaDoc
ja avaamalla schemaDoc/index.html
omassa selaimessa.
Tietokannan voi tyhjätä komennolla
lein dbclean
Tämän jälkeen migraatiot pitää ajaa uudelleen.
Migraatiot voi ajaa myös JAR:lla. Katso Ajettava jar
Migraation voi luoda:
lein genmigration /path/to/migrations "Title of the migration"
Erityisesti kehitysympäristöissä kuten QA:lla voi tulla tilanne, jossa eri kehityshaaroja asenneltaessa tietokannan migraatiot voivat mennä solmuun. Yleisin virhetilanne on se, että asennettavasta versiosta puuttuu jokin migraatio, joka palvelimella olevasta versiosta löytyy ja tästä syystä asennus epäonnistuu migration checksum mismatch-virheeseen.
Tämän voi korjata seuraavalla tavalla:
- Yhdistä tietokantaan. Ohje. Lisää apua saa Ylläpidon kehittäjiltä.
- Hae Flyway schema historia:
SELECT * FROM flyway_schema_history;
- Poista kyseisestä taulusta ongelmia aiheuttava(t) rivi(t) eli rivit, joita ei ole mukana haarassa jonka haluaisit asentaa:
DELETE FROM flyway_schema_history WHERE installed_rank = <numero>;
- Poista kannasta myös ne muutokset, joita kyseisissä migraatioissa olevat SQL-käskyt tekivät. Esim droppaa columnit joita luotiin:
ALTER TABLE <taulu> DROP COLUMN <nimi>;
Tämän jälkeen haarasi pitäisi asentua normaalisti.
Ulkoiset API-kutsut voidaan mockata ja dev-profiililla onkin paljon tällaisia API-kutsuja, katso kaikki symbolit joiden nimi on mock-routes.
Kehitysresursseissa on konfiguroitava HTTP-asiakasohjelma, jonka GET- ja
POST-kutsut voidaan yliajaa. Tämä toimii ainoastaan test
-profiililla.
Kontin luonti käy komennolla make stamps/db-image
tai käsin:
cd scripts/postgres-docker
docker build -t ehoks-postgres .
docker volume create pgdata
Kontin ajaminen onnistuu make stamps/db-running
tai käsin:
docker run --rm --name ehoks-postgres -p 5432:5432 \
--volume pgdata:/var/lib/postgresql/data \
-e POSTGRES_HOST_AUTH_METHOD=trust ehoks-postgres
Palaute-backend kirjoittaa tietoja suoraan vanhan herätepalvelun kantaan (ainakin niin kauan kuin kyseinen kanta on olemassa). Näiden kirjoitusten paikallinen testaus käyttää paikallista DynamoDB:tä, jonka voi ajaa komennolla:
make stamps/local-ddb-schema
Sovelluksessa on generoidaan automaattisesti kullekin HTTP-metodille (POST,
PATCH) omat schemat. Schemaan määritellään jokaiselle HTTP-metodille, onko
kenttä tämän HTTP-metodin payloadissa pakollinen (:required, oletus),
valinnainen (:optional) vai kielletty (:excluded). HTTP-metodien vaihtoehdot
ovat :any
, :get
, :post
, :put
tai :patch
. Myös kentän tyypin voi
määritellä metodikohtaisesti.
Tietorakenne, josta API-schemat generoidaan, näyttää tällaiselta:
{:avain {:methods {:any :required
:post :excluded}
:description "Jokin selite"
:types {:any s/Int}}
:toinen {:methods {:any :optional
:post :required}
:description "Toinen selite"
:types {:any s/Str
:get s/Int}}}
Tähän tietorakenteeseen täytyy lisätä metadataan nimi :name
, :doc
ja
:restful
-vipu (true
), jotta dokumentaatio generoituu oikein.
Restful-tyyppistä schemaa käytetään ainoastaan HTML-muotoisen taulukkodokumentaation generointiin.
Sovellus tukee dev-profiilissa dummy-JSON-rajapintoja. Laita valmiit
JSON-tiedostot kansioon resources/dev/dev-routes
. Tiedostoa vastaava endpoint
luodaan automaattisesti muuttamalla alaviivat kauttaviivoiksi. Esimerkiksi
/hello/world_boom
endpoint tarjoilee hello_world__boom.json
-tiedoston.
Kun sovellusta ajetaan dev-profiililla, on kehittäjälle tarjolla dev-tools-rajapinta. Tämä on kokoelma erilaisia työkaluja, joilla voi muokata helposti arvoja tietokannassa (oppijat ja opiskeluoikeudet) ja kirjautuneen käyttäjän istuntoa. Istunnon muokkaus onnistuu sekä oppijan että virkailijan puolella.
Paikallisessa kehityksessä on toteutettu mock-kirjautumiset, joihin pääset käsiksi environmentista löytyvillä linkeillä.
Rajapinta Huom dev-tools rajapinnan Swagger-dokumentaatio ei tällä hetkellä toimi. Koodissa kommentti.
Testidataa löytyy resources/dev/demo-data
kansiosta. Näiden avulla pystyy
hokseja luomaan joko:
- skripteillä scripts/create-curl-session.sh ja scripts/upload-hoks.sh tai
- vastaavasti komennolla
make stamps/example-data
- swaggerilla (käyttämällä rajapintaa POST /ehoks-virkailija-backend/api/v1/virkailija/oppijat/{oppija-oid}/hoksit) tai
- komennolla
lein import resources/dev/demo-data/hoksit.json
.
Rajapinnan käyttö on suositeltavampi vaihtoehto koska lein import
ohittaa
skeemavalidoinnit ja siten sen avulla pystyy luomaan dataa jota järjestelmä ei
oikeasti hyväksyisi.
Repositorioon on lisätty jonkin verran selvitystyötä ja testaamista helpottavia skriptejä. Näiden toimintaperiaatteesta voi lukea niille osoitetusta dokumentaatiosta.
eHOKSista viedään tiedot päivittäin Lampeen. Prosessia hoitaa
lampi-export
-niminen ajastettu ECS Task. Docker image kyseiselle taskille
luodaan ajamalla Create Lampi export runner image
GitHub workflow käsin valitusta haarasta (oletuksena master). Infra-määritykset
ECS Taskille löytyvät cloud-base
-reposta.
ECS Task kutsuu eHOKSin tietokannassa olevia funktioita, jotka päivittävät
reporting
-skeemaan ajantasaiset tiedot public
-skeeman tauluista ja
näkymistä. reporting
-skeeman rakenne eroaa operatiivisesta skeemasta jossain
määrin, jotta eHOKS-tietojen hyödyntäminen Lammesta olisi helpompaa.
Oletuskonfiguraatio on oph-configuration/default.edn
. Arvoja voi yliajaa luomalla oman
konfiguraatiotiedoston ja antamalla sen joko CONFIG
-ympäristömuuttujassa,
JVM system propertyssä config
tai kehityspalvelimen käynnistysparametrina.
Konfiguraatiotiedostot yhdistetään niin, että oma kustomoitu tiedosto yliajaa vain ne arvot, mitkä siinä on määritelty. Konfiguraatio validoidaan ladattaessa.
Sovellus käyttää CAS-tunnistautumista ulkoisten rajapintojen kanssa. Lisää CAS-tunnukset ja sovelluksen tunniste (ent. client sub system code) ennen rajapintojen käyttämistä.
Sovellus autentikoi rajapinnan kutsut CAS-palvelusta. Jokaisessa pyynnössä tulee olla ticket mukana. Tämän perusteella haetaan palvelukäyttäjän tiedot ja varmistetaan että käyttäjällä on oppijan opiskeluoikeuden kautta oikeus luoda tai päivättää oppijan HOKSia.
Rajapintaa kutsuttaessa pitää tuoda seuraavat headerit:
header | selite | Lisätietoa |
---|---|---|
Caller-Id | OPH:n rajapintojen yhteinen tunniste | Kutsujan tunnisteen (Caller-Id) lisääminen rajapintakutsuihin |
ticket | Validi CAS service ticket | CAS-tunnistautuminen rajapinnassa (eHOKS) |
Ajettava jar riippuvuuksineen luodaan:
lein uberjar
Ja ajetaan:
java -jar target/ehoks-standalone.jar
JAR:lle voi antaa myös komentoina --help
tai --run-migrations
. Jälkimmäinen
ajaa tietokantamigraatiot.
Ehoks luo jokaisen Hoksin tallennuksen yhteydessä rivit Hoksin oppijasta
tauluun oppijat
, sekä Hoksin opiskeluoikeudesta tauluun opiskeluoikeudet
.
Näille riveille haetaan tietoja Oppijanumerorekisteristä sekä Koskesta.
Näitä tietoja indeksoidaan myös asennusten ja uudelleenkäynnistysten
yhteydessä niille Hokseille, joille ei löydy rivejä yllä mainituista
indeksitauluista. Tietojen hakuun rajapinnoista käytetään hoksin juuressa (eli
"hoksit" taulun rivillä) olevia kenttiä opiskeluoikeus_oid
ja oppija_oid
.
Indeksointi on mahdollista käynnistää myös virkailijan käyttöliittymästä. Käyttöliittymästä voi myös uudelleenindeksoida opiskeluoikeudet indeksiä opiskeluoikeus-oidin tai koulutustoimijan perusteella.
Indeksointia tehdään siksi, ettei Oppijanumerorekisteriä ja Koskea kuormiteta jatkuvalla oppijoiden tietojen hakemisella. Esimerkiksi virkailijan käyttöliittymän listauksissa näytetään tietoja oppijoista ja heidän opiskeluoikeuksistaan. Tätä varten on parempi käyttää Ehoksiin indeksoituja tietoja, kuin hakea niitä jatkuvasti rajapintojen kautta.
oid | nimi |
---|---|
1.2.246.562.24.44207125156 | Onni Opiskelija |
oid | oppija_oid | oppilaitos_oid | koulutustoimija_oid | tutkinto_nimi | osaamisala_nimi | paattynyt | hankintakoulutus_jarjestaja_oid | hankintakoulutus_opiskeluoikeus_oid | koski404 |
---|---|---|---|---|---|---|---|---|---|
1.2.246.562.15.28526155046 | 1.2.246.562.24.97452958511 | 1.2.246.562.10.36044172441 | 1.2.246.562.10.91095189945 | {"en": "Vocational qualification in Logistics", "fi": "Logistiikan perustutkinto", "sv": "Grundexamen i logistik"} | {"fi": "Kuljetuspalvelujen osaamisala", "sv": "Kompetensområdet för transportservice"} | null | null | null | null |
Oppijaindeksiä varten on toteutettu automaatioratkaisu
Oppijanumerorekisterin muutosten siirtymisestä Ehoksiin. Toistaiseksi Kosken
muutokset eivät siirry automaattisesti Ehoksiin. Poistuneita
opiskeluoikeuksia varten on kuitenkin luotu ratkaisu, joka merkitsee
opiskeluoikeuksindeksiin koski404
kentän trueksi. Sen toteutusta voi
tarkastella oph/ehoks/hoks.clj
tiedoston update-opiskeluoikeudet
-funktiosta. Toistaiseksi koski404 -riveille ei tehdä mitään, mutta ne voisi
jatkossa poistaa, mutta tästä tulee tehdä oma tikettinsä. Oletettavasti myös
poistuneeseen opiskeluoikeuteen kiinnitetty hoks tulisi poistaa.
Tähän alle kerätään ohjeita erilaisista asioista mitä kehittäjien tulee ottaa huomioon työskennellessään eHOKS:n ja Herätepalvelun parissa.
Kehittäjien vastuulla on seurata Slackin valvontakanavia mahdollisten ongelmatilanteiden varalta. Pääasiassa virheet koskettavat Herätepalvelua ja usein sen virheet eivät vaadi toimenpiteitä kehittäjiltä.
eHOKS-Herätepalvelu -kokonaisuudessa on AWS:ssä kolme eri SQS DLQ-jonoa joihin syntyy erilaisten virhetilanteiden johdosta viestejä.
- sade-services-heratepalvelu-tep-HerateDLQ (TEP-osio)
- sade-services-heratepalvelu-HerateDeadLetterQueue (AMIS-osio)
- sade-services-heratepalvelu-ONRhenkilomodifyDLQ (ONR-muutosten automatisointi)
Nämä kolme jonoa on hyvä tarkastaa ja mahdollisesti tyhjentää kerran päivässä. Tämä tehdään manuaalisesti AWS Consolesta seuraavalla tavalla:
- Mene SQS-jonojen listaus ja valitse haluttu DLQ.
- Avaa SQS:n sivulta "Lambda triggers" välilehti.
- Valitse triggeri ja paina "View in Lambda" -painiketta. Lambdan sivu avautuu.
- Valitse "Configuration" -välilehti ja sieltä kohta "Triggers".
- Valitse triggeri ja paina "Edit" -painiketta.
- Valitse avautuvalta sivulta "Activate trigger" ja paina "Save" -painiketta. "Activate trigger" saattaa olla automaattisesti valittuna.
- SQS-listauksesta voit seurata DLQ:n tyhjentymistä. Kun DLQ-jonossa ei ole enää viestejä, voit käydä disabloimassa triggerin ottamalla ruksin pois "Activate trigger" -valinnasta ja painamalla "Save". Tämä täytyy muistaa tehdä, ettei virhetilanteissa DLQ palauta viestejä heti takaisin käsittelyyn.
- DLQ on nyt tyhjennetty.
Toistaiseksi tämä toimenpide tehdään manuaalisesti, mutta tulevaisuudessa olisi mahdollista automatisoida DLQ:n tyhjennys. Tämän voisi esimerkiksi tehdä siten, että luodaan kaksi Lambdaa, joista toinen asettaa trueksi DLQ:n tyhjentävien Lambdojen triggerin (cdk:ssa CfnEventSourceMapping) "enabled" -arvon ja toinen päinvastoin asettaisi sen falseksi. Sen jälkeen ajastettaisiin nämä Lambdat käynnistymään esimerkiksi joka yö siten, että enabloidaan käsittely klo 12AM ja disabloidaan 2AM.