Aiemmista ohjeista muuttuneet kohdat on merkattu tällaisella laatikolla.

EXAM käännetään, paketoidaan ja käynnistetään SBT-, NPM- ja angular-cli-työkalujen avulla, sitä ajetaan Play-sovelluspalvelimen päällä ja Apache-HTTP-proxypalvelimen takana. Autentikointi on ulkoistettu Shibboleth-SSO-toteutukselle, josta vastaavat eri HAKA-organisaatiot.

Järjestelmäriippuvuudet

Tarkat ohjeet riippuvat käyttöjärjestelmästä. Tämä on RHEL 9:n perusteella tehty esimerkki.

Uusi Javan versiovaatimus on 21 eli kirjoitushetkellä tuorein LTS-julkaisu.

Asenna Java versio 21 (LTS). Esimerkiksi:

$ sudo yum install java-21-openjdk

Asenna SBT, esimerkiksi:

$ sudo sh -c 'curl -L https://www.scala-sbt.org/sbt-rpm.repo > /etc/yum.repos.d/sbt-rpm.repo'
$ sudo yum install sbt

Asenna Apache HTTP-palvelin, esim:

$ sudo yum install httpd
$ sudo systemctl enable httpd

Asenna postgresql, esim:

$ sudo dnf module install postgresql:15/server
$ sudo postgresql-setup --initdb

Muokkaa postgresql-serverin autentikointiasetuksia. Nähtävästi play ei voi yhdistää tietokantaan ilman, että paikallisia IP-yhteyksiä ei suojata md5:llä. Halutessaan voi luottaa lokaaliyhteyden olevan automaattisesti autentikoitu (trust), sillä se helpottaa ainakin komentorivikäyttöä:

$ sudo -u postgres vi /var/lib/pgsql/data/pg_hba.conf
// muokkaa tiedoston lopussa olevia asetuksia vaikka näin
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            ident
host    replication     all             ::1/128                 ident

Käynnistä tietokantapalvelin ja aseta se samalla käynnistymään automaattisesti.

$ sudo systemctl enable postgresql.service
$ sudo systemctl start postgresql.service

Asenna Git, esim:

$ sudo yum install git

NodeJS:n vaadittu minimiversio nyt 18.

Asenna NodeJS, esim:

$ curl -sL https://rpm.nodesource.com/setup_20.x | sudo bash -
$ sudo dnf install nodejs20 -y

Tietokanta

Luo palvelimelle tietokanta exam (voi toki nimetä vapaastikin, mutta tässä ohjeessa käytetään nimeä exam) ja käyttäjä haluamillasi tunnuksilla, esimerkiksi:

$ sudo -u postgres createuser -SPRD exam
$ sudo -u postgres createdb --owner=exam exam

Jos kaikki on mennyt oikein, seuraavan kirjautumisen pitäisi onnistua (olettaen, että olet sallinut lokaaliyhteydet kaikille käyttäjille (ks. yllä)):

$ psql -Uexam
psql (15.5)
Type "help" for help.
exam=>

Poistu psql-konsolista komennolla \q tai ctrl+D

Jos haluat tuoda tietokannan backupista:

$ psql -Uexam exam < dump.psql

Jos haluat ajaa integraatiotestejä tarvitset lisäksi testitietokannan:

$ createdb -Upostgres --owner=exam exam_test

Apache & Shibboleth

Lisää reverse proxy Exam-järjestelmälle. Apachen tai valitun http-proxyn konfiguraatioon tulee lisätä myös organisaatiokohtaiset shibboleth-asetukset. Portti 9000 on Playn oletusportti. Esimerkki:

/etc/httpd/conf.d/exam.conf
<VirtualHost 193.166.44.29:443>
	ProxyPreserveHost On
	ServerName https://dev.exam.csc.fi
	# no proxy for Shibboleth
	ProxyPass /Shibboleth.sso/ !
	ProxyPass / http://127.0.0.1:9000/
	ProxyPassReverse / http://127.0.0.1:9000/

	# Koko asennus Shibboleth-autentikoinnin taakse
	<Location "/">
    	AuthType             shibboleth
    	ShibRequestSetting   requireSession 1
    	ShibUseHeaders       On
    	# tämä olisi kaiketi suositusten mukainen tapa välittää käyttäjäattribuutit, mutta AJP-protokollaa ei oikein mikään framework enää ainakaan nykyisin tue
    	# ShibUseEnvironment On 
    	require              valid-user
	</Location>

</VirtualHost>


Examiin on toteutettu erilaisia integraatiorajapintoja ulkopuolista tiedonhakua ja -siirtoa varten. Exam-sovellus ei rajoita pääsyä näihin rajapintoihin mitenkään, joten autorisointi tehdään apachen konfiguraatioissa. Pääsyjen toimivuutta pitää tarkistaa, esim. ottamalla rajapintaan yhteyttä verkko-osoitteesta, jolla ei pitäisi olla pääsyä, Haka-kirjautuneena ja ilman Haka-kirjautumista. Näillä kummallakaan ei pitäisi saada rajapinnasta tietoja:

/etc/httpd/conf.d/exam.conf
# interface for getting exam records
<LocationMatch /integration/record>
 
 # if you want to block all connections to interface
  Require all denied 

 # if you want to allow connections only from specific ip address/addresses use this instead
 # Require ip x.x.x

</LocationMatch>

# interface for getting reservation/room/exam/reports data
<LocationMatch /integration/(reservations|rooms|exams|reports)>   
  
  # if you want to block all connections to interfaces 
  Require all denied 

 # if you want to allow connections only from specific ip address/addresses use this instead
 # Require ip x.x.x 

</LocationMatch>

# interface for IOP services, allow access from dedicated XM server 
<LocationMatch /integration/iop>
# When using interoperability services (exam visits and/or joint exams) use this. This ip is for IOP test service.
  Require ip 86.50.224.215

# If not using IOP services (exam visits and/or joint exams) use this instead
# Require all denied

</LocationMatch>

Toteuttaessa suoritus-, varaus- ja tenttitietoja hyödyntäviä palveluita, on syytä käyttää keskitettyä instanssia/proxya, jolla on kiinteä IP. Näin autorisoinnin konfigurointi on yksinkertaista. Alimpana listattu yhteiskäyttöisyyskonfiguraatio  pitää ottaa käyttöön jos yhteiskäyttöisyystoiminnallisuutta eli tenttivierailuja ja/tai yhteistenttiä halutaan käyttää (ks. yhteiskäyttöisyysasetukset).

Shibbolethin attribuuttien mäppäys (/etc/shibd/attribute-map.xml)

Kun konfiguroit shibbolethia, pitäisi seuraavat attribuutit saada http-headerien mukana Exam-järjestelmään asti:

Virallinen nimi
Nimi Examissa
Käyttö
Pakollinen
Muuta
eduPersonAffiliationunscoped-affiliationkäyttäjärooli(tick)
eduPersonPrincipalNameeppnkäyttäjätunnus(tick)
mailmailsähköpostiosoite(tick)
snsnsukunimi(tick)
displayNamedisplayNameetunimi(tick)
preferredLanguagepreferredLanguagekieli
oletus on englanti
schacPersonalUniqueCodeschacPersonalUniqueCodeopiskelijanumero
tieto vaaditaan, jos opiskeluoikeuden tarkistus kolmannen osapuolen järjestelmästä on käytössä
employeeNumberemployeeNumbertyöntekijän numero
kirjataan suoritukselle opettajan osalta
logout-urllogouturlShibboleth IdP -uloskirjautumisen URL
URL, jonne käyttäjä ohjataan exam-uloskirjautumisen jälkeen IdP-uloskirjautumista varten
schacHomeOrganizationhomeOrganisationorganisaation tunnus
toistaiseksi käyttöä ainoastaan jaetuissa asennuksissa, joissa käyttäjäkunta koostuu useamman organisaation henkilöistä (katso: Organisaatiotietojen tuonti Examiin)

Attribuutit tulee olla URL-enkoodattuna (https://shibboleth.atlassian.net/wiki/spaces/SP3/pages/2065334391/RequestMapper):

/etc/shibd/shibboleth2.xml
    ...
	<RequestMapper type="Native">
        <RequestMap applicationId="default" encoding="URL">
            <Host scheme="https" name="dev.exam.csc.fi">
                <Path name="secure" authType="shibboleth" requireSession="true"/>
            </Host>
        </RequestMap>
    </RequestMapper>
    ...

Exam-applikaatio

Alustus

Lisää järjestelmään haluamallasi tavalla rajoitettu käyttäjä/rooli (tässä: exam/exam).

$ sudo groupadd exam
$ sudo useradd -g exam exam

Luo Examin tarvitsemat hakemistot ja anna niille tarvittavat oikeudet, esimerkiksi:

$ sudo mkdir /opt/exam                         // <- asennushakemisto
$ sudo chown -R exam.exam /opt/exam
$ sudo mkdir -p /var/lib/exam/attachments      // <- liitetiedostojen hakemisto
$ sudo chown -R exam.exam /var/lib/exam
$ sudo mkdir /var/log/exam                     // <- lokihakemisto
$ sudo chown -R exam.exam /var/log/exam

Lähdekoodi

Ota gitiä apuna käyttäen exam-lähdekoodi repositoriosta haluamaasi hakemistoon (tässä käytetään /opt/exam-hakemistoa, jolloin tuloksena on asennushakemisto /opt/exam/exam

$ cd /opt/exam
$ sudo -u exam git clone https://github.com/CSCfi/exam.git
$ cd exam

Tämän jälkeen käytössäsi on viimeisimmän julkaisun lähdekoodit. Ne löytyvät haarasta master, jonka pitäisi olla valittuna oletuksena alustuksen jälkeen. Voit siirtyä haarojen välillä näin:

$ sudo -u exam git checkout dev
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.

Jos haluaa tietyn version käyttöön, pitää tehdä checkout-komento julkaisun tägille:

$ sudo -u exam git checkout tags/6.2.0
Note: checking out 'tags/6.2.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
...

Voit listata kaikki tägit komennolla

$ git tag

Examin asetukset

Asetusten nimeäminen muuttunut. Aiemmin sitnet-alkuiset nimet on korvattu exam-etuliittellä. Tämä siksi, että olemme pyrkineet pääsemään eroon historiallisesta sitnet-termistä slightly smiling face 

Asetuksia muokataan asetustiedostojen kautta. Tiedostot sijaitsevat hakemistossa conf. Oletuksena Play käyttää tiedostoa conf/application.conf, mutta tämän voi ohittaa määrittelemällä vaihtoehtoisen asennustiedoston antamalla käynnistysskriptille argumentin -Dconfig.file=conf/myconfig.conf (tai -Dconfig.resource=myconfig.conf).

Versiopäivityksen yhteydessä on aina syytä ottaa versionhallinnasta uusin asetustiedosto pohjaksi, jonka päälle kirjoittaa omat asetuksensa. Sisäisiin asetuksiin (joita ei ole tässä ohjeessa dokumentoitu) on nimittäin saattanut tulla muutoksia, joita ilman ohjelmisto ei välttämättä toimi oikein.

HTTP-proxyyn liittyvät asetukset

Jos reverse proxy ei ole localhost-osoitteessa, täytyy Play eksplisiittisesti konfiguroida luottamaan sen tarjoamaan X-Forwarded-For-headerin sisältämään osoitetietoon. Käyttäjän IP:tä käytetään tarkistettaessa onko käyttäjä varaamallansa tenttikoneella tentin alkaessa. Oletusarvoisesti Play ei luota X-Forwarded-For-headeriin, jos proxy on eri IP:ssä kuin Play-applikaatio. Lisätietoa: https://www.playframework.com/documentation/3.0.x/HTTPServer

play.http.forwarded.trustedProxies=[123.123.123.123]

Play-salasana

Play käyttää applikaatiokohtaista salasanaa mm. sessioavainten allekirjoitukseen ja enkryptaustoimintoihin. Salasana on vapaavalintainen ja sen voi määrittää asetustiedostossa

# Secret key
# ~~~~~
# The secret key is used to secure cryptographics functions.
# If you deploy your application to several instances be sure to use the same key!
play.http.secret.key="changeme"

mutta suositeltavampaa on määritellä salasana EXAMIn käynnistysskriptissä komentoriviparametrina (ks. kohta examin käynnistys):

-Dplay.http.secret.key='5;H<gq;9A5FIv6VE3ZdY^nMIe^<hr1GfjTW^XMW1joK3Kx6ME8N76yhI>pMf8[Qt'

Salasanan voi generoida mm. näin

$ sbt
...
[exam] $ playGenerateSecret
Generated new secret: 5;H<gq;9A5FIv6VE3ZdY^nMIe^<hr1GfjTW^XMW1joK3Kx6ME8N76yhI>pMf8[Qt
[success] Total time: 0 s, completed 15 Feb 2024, 21.55.25

Lisätietoa: https://www.playframework.com/documentation/3.0.x/ApplicationSecret

Tietokantayhteys

Yhteysparametrit examin tietokantaan täytyy määrittää asetustiedostossa. Jos tietokanta on luotu tässä dokumentissa kuvatulla tavalla, näyttävät parametrit tältä:

db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://localhost/exam"
db.default.user=exam
db.default.password=exam

Käyttäjäroolien määritys

Exam tukee kolmea käyttäjäroolia:

  • teacher (opettaja)
  • student (opiskelija)
  • admin (pääkäyttäjä)

Käyttäjärooli asetetaan käyttäjälle kun hän kirjautuu järjestelmään ensimmäisen kerran HAKA:n kautta unscoped-affiliation attribuutin mukaan. Käyttäjällä voi olla myös useampi käyttäjärooli.
Koska unscoped-affiliation attribuutin käyttö ei ole yhdenmukaista eri organisaatioissa, voidaan Examin konfiguraatiossa määritellä, mitä Examin roolia unscoped-affiliation-arvot vastaavat.

esimerkiksi:

exam.roles = {
  student = [
    "student"
  ]
  teacher = [
    "faculty"
    "affiliate"
    "alum"
  ]
  admin = [
    "staff"
  ]
}

Unscoped-affiliation attribuutti voi sisältää myös useamman roolin puolipisteillä erotettuna. Tässä tapauksessa exam vertailee kutakin roolia omiin määrityksiinsä ja osuman kohdalla asettaa käyttäjälle kyseisen roolin. Esimerkiksi jos vaikka unscoped-affiliation on "x;y;z" ja examin määrityksessä olisi vaikkapa exam.roles.teacher="a;b;z;" ja exam.roles.student="c;y;d", tulisi käyttäjälle käyttäjäroolit teacher eli opettaja sekä student eli opiskelija.

Hostname

Järjestelmän hostname asetetaan exam.application.hostname muuttujaan. Muuttujaa käytetään mm. erilaisten linkkien generoinnissa.

exam.application.hostname="https://exam.uni.org"

Sähköpostiasetukset

Exam lähettää erilaisia muistutusviestejä ja raportteja sähköpostilla. Sähköpostiasetukset konfiguroidaan asetustiedostossa

play.mailer.host=smtp.yliopisto.fi
play.mailer.port=587
play.mailer.ssl=true
play.mailer.tls=true
play.mailer.user="exam@yliopisto.fi"
play.mailer.password="111111111"

Järjestelmän sähköpostiosoite

Osoite, jolla järjestelmän lähettämät sähköpostit lähtevät vastaanottajalle.

# mail address for the system, appears in From-header of emails sent by the app.
exam.email.system.account="exam-no-reply@csc.fi"

Opintohallintajärjestelmän URL

Opintohallintajärjestelmän osoite asetetaan muuttujaan. Muuttujaa käytetään mm. sähköpostiviesteissä linkkien generointiin, esimerkiksi:

exam.baseSystemURL="http://base.uni.org"

Opintojaksohaun tiedot

Opintojaksoja voi hakea ulkopuolisesta järjestelmästä. Haun saa päälle asettamalla exam.integration.courseUnitInfo.active=trueHaussa käytettävät URLit määritetään erikseen:

# External course interface in use: true=on, false=off
exam.integration.courseUnitInfo.active = true

# URL configuration for the course interface(s). Each URL should have the course code either as path parameter or query
# parameter. Use ${course_code} for marking that part of the path.
# You can specify URLs on a per-organisation basis in order to use different URLs for users belonging to different
# organisations. In that case the key should match with "code" column of organisation table.
# "default" is used if no other match is found. You can remove the "default" key if you don't want a default URL at all.
exam.integration.courseUnitInfo.url = {
  default = "http://base.uni.org?courseCode=${course_code}"
  a.uni.org = "http://a.uni.org?courseCode=${course_code}"
  b.uni.org = "http://b.uni.org?courseCode=${course_code}"
} 

(warning) Huom. Jotta organisaatiokohtainen URL-konfiguraatio toimii, täytyy organisaatiotieto olla tuotuna EXAMiin (ks. Organisaatiotietojen tuonti Examiin). Jos tarvetta organisaatiokohtaiselle konfiguraatiolle ei ole, riittää että määrittelee pelkän default-URLin:

exam.integration.courseUnitInfo.url = {
  default = "http://base.uni.org?courseCode=${course_code}"
}

Tenttien luominen tulevaisuudessa alkaviin opintojaksoihin

Oletuksena EXAMissa tentaattori/opettaja löytää tenttiä luodessaan opintojaksohaulla vain sellaisia opintojaksoja/toteutuksia jotka ovat voimassa eli joiden alkamisaika on jo ollut eikä päättymisaika ole vielä ollut. Tällä asetuksella voidaan asettaa aikaikkuna jonka verran tulevaisuudessa alkavia opintojaksojen toteutuksia löytyy haulla ja voidaan liittää tenttiin.

Esimerkiksi tenttien luomisen kolme kuukautta ennen opintojakson toteutuksen alkamista voi mahdollistaa kolmen kuukauden aikaikkunalla eli asettamalla asetukseen arvon P3M.

# Period during which it is allowed to import a course before its starting date.
# For example if course has a starting date of June 1st and period is set to 3 months, the course can be imported
# starting March 1st. Value is to be provided in ISO 8601 duration format. Default is zero days.
exam.integration.courseUnitInfo.window = "P0D"

Osallistumisoikeuden tarkistus

Opiskelijoiden oikeus ilmoittautua tentteihin voidaan rajoittaa koskemaan tiettyjä opintojaksoja. Exam ei itse ylläpidä tietoa oikeuksista, vaan kyseinen tieto haetaan perusjärjestelmästä. Perusjärjestelmän rajapinnan tulee pystyä ottamaan parametrina opiskelijan yksilöivä tunniste, jonka perusteella sen tulee palauttaa lista opintojaksojen yksilöivistä tunnisteista.

# enable / disable checking of permission to enroll for exams
exam.integration.enrolmentPermissionCheck.active=true
# Which user data to use as unique identifier. Permitted values are userIdentifier and eppn.
exam.integration.enrolmentPermissionCheck.id = "userIdentifier"
# URL for the API implementing this check. The URL should have the employee number either as path parameter or query
# parameter. Use ${employee_number} for marking that part of the path.
# examples: https://x.y.z/enrolmentPermissions?id=${employee_number}
#           https://x.y.z/enrolment/${employee_number}/permissions
# Response should provide EXAM with the identifiers for the courses that the person is allowed to enroll for.
exam.integration.enrolmentPermissionCheck.url="https://x.y.z/enrolment/${employee_number}/permissions"

Rajapintakutsujen API-avain

Opintohallinnon järjestelmien (kuten Sisu, Peppi tai Oodi) rajapintoihin (opintojaksotietojen haku sekä ilmoittautumisen tarkistus) tehtävän URL-kyselyn tietoturvan varmistamiseksi kyselyn mukana Header-tietona voidaan välitettää API-avain, jonka tarkistamalla opintohallinnon järjestelmä voi varmistua, että kysely tulee Examista.

# API key configuration for the above external interfaces (course import and enrolment permission).
# Optional. Will be passed as an HTTP header
exam.integration.apiKey = {
  enabled = false,
  name = "API_KEY",
  value = "somevalue"
}

Liitetiedostojen hakemisto

Exam tallentaa tenttiin ja kysymyksiin liittyvät tiedostot levylle. Tiedostojen juurihakemiston polku voidaan asettaa kofiguraatiotiedostossa olevaan muuttujaan. Jos polku ei ole absoluuttinen, luodaan hakemisto suhteessa examin juurihakemistoon (/opt/exam/exam/target/universal/stage). Huomioithan että examin käyttäjällä on kirjoitusoikeudet kyseiseen hakemistoon.

# Attachment directory
exam.attachments.path=/var/lib/exam/attachments

Tenttien kestot

Tenttien mahdolliset kestot minuuteissa määritellään asetuksissa (exam.exam.durations). Kestot näkyvät käyttöliittymässä siinä järjestyksessä kuin ne on tässä määritelty. Oletusarvona käytetään ensimmäistä kestoa. Lisäksi omakonetenteille on mahdollista määrittää vapaavalintaisia kestoja, joiden raja-arvot määritellään niinikään asetuksissa (exam.exam.minDuration ja exam.exam.maxDuration). 

Huom: maxDate-asetus on poistunut, koska omakonetenttitilaisuuksien myöhäisintä päivämäärää rajaa tästedes tenttiperiodin päättymispäivä.


# Exam durations available for choosing, in minutes. The order is the same as the one end user sees on UI.
# First duration is used as default.
exam.exam.durations = "45,90,110,180"
# Exam custom duration field min max values. Used also for verification. Empty values will use default (1 - 300)
exam.exam.maxDuration = 300
exam.exam.minDuration = 1

Oletusaikavyöhyke

Käyttäjien oletusaikavyöhyke, jota käytetään mm. tenttitilojen kulloisenkin kellonajan määritykseen ja ajan esittämiseen sähköposteissa. Jos oletuksena on, että tenttitilat ja järjestelmän käyttäjät ovat pääasiassa Suomessa, kannattaa käyttää oletusarvoa:

# application timezone, used for:
# - formatting timestamps in emails to users
# - setting default timezone for exam rooms, this affects how and when they are eligible for reservations
# - deciding the moment when user should be having an exam, system needs to take possible DST into consideration
# For allowed values see: http://joda-time.sourceforge.net/timezones.html
exam.application.timezone="Europe/Helsinki"

Arvosana-asteikon muokattavuus

Tällä asetuksella voidaan estää opettajaa muuttamasta arvosana-asteikkoa tekemilleen tenteille. Asetus on järkevää ottaa pois käytöstä silloin, kun halutaan että opintojaksolle määritelty arvosana-asteikko määrittää aina myös kaikkien siihen kuuluvien tenttien asteikot.

# Enable / disable possibility of users to override course grade scale for individual exams associated with the course.
exam.course.gradescale.overridable=true

Opiskelijanumeroon liittyvät asetukset

Jos opiskelijalle on HAKAssa mahdollista määritellä useampi opiskelijanumero (schacPersonalUniqueCode), voidaan ne kaikki lukea Examiin seuraavin asetuksin.

# Enable / disable support for multiple student IDs. By default exam parses only the last ID it gets from authentication
# provider. Enabling this support allows for reading in all the IDs provided should there be multiple ones.
exam.user.studentIds.multiple.enabled = false
# Organisations associated with student IDs. A comma separated list of organisations. IDs will be presented on the UI
# using this order
exam.user.studentIds.multiple.organisations = "org1.org,org2.org,org3.org"

Liitetiedoston maksimikoko

Oletuksena on 50MB. Tätä suurempien tiedostojen tallennus on estetty.

# maximum allowed attachment file size in bytes
exam.attachment.maxsize=50000000

Tenttisuoritusten vanhentumisaika

Tällä voidaan määritellä kesto, jonka jälkeen prosessin läpikäyneet tenttisuoritukset poistuvat järjestelmästä. Ajan umpeuduttua suoritukset siirtyvät DELETED-tilaan, jolloin ne eivät enää näy käyttöliittymässä kenellekään ja niiden omistajuustiedot pyyhitään, mutta itse tentit jäävät vielä tietokantaan esim. tilastointitarkoituksia varten. Oletuskesto on kuusi kuukautta.

# Period after which processed exams (aborted, registered or archived) are marked as deleted and thus hidden from users.
# Value is to be provided in ISO 8601 duration format, default is six months
exam.exam.expiration.period="P6M"

Anonyymi arviointi 

Tämä on automaattisesti käytössä yhteistenteissä ja niiden osalta tällä asetuksella ei ole vaikutusta.

Anonyymissa arvioinnissa tentaattori ei saa tietoonsa kenen suoritusta hän arvioi. Voit mahdollistaa anonyymin arviointitoiminnallisuuden asetuksissa.

# Enable / disable anonymous review process globally.
exam.exam.anonymousReview = false

Yhteiskäyttöisyysasetukset

Yhteiskäyttöisyydellä tarkoitetaan mahdollisuutta siirtää tietoja eri oppilaitosten ja niiden EXAM-asennusten välillä sekä hyödyntää tästä syntyviä käyttötapauksia.

Tässä vaiheessa tuetaan

  1. opiskelijan mahdollisuutta suorittaa "etänä" oman oppilaitoksensa tenttejä varaamalla aikoja ulkopuolisen oppilaitoksen EXAMista. Käänteisesti näin mahdollistetaan ulkopuolisten opiskelijoiden tenttisuoritukset oman oppilaitoksen tiloissa EXAMia apuna käyttäen. 
  2. mahdollisuutta laatia, tenttiä ja arvioida niin sanottuja yhteistenttejä. Opettajien on mahdollista laatia yhteistenttejä yhteistyössä eri oppilaitosten välillä. Samoin osallistujat voivat tenttiä yhteistenttejä eri oppilaitoksista käsin. Lisäksi suoritusten arviointi voidaan tehdä yhteistyönä oppilaitosten välillä.

Jos tätä toiminnallisuutta halutaan tukea, tulee olla yhteydessä EXAMin kehittäjätiimiin, sillä organisaation tiedot tulee ensin lisätä yhteiskäyttöisyysjärjestelmään. 

# Interoperability (IOP) services configuration
# Hostname of the IOP server provided to you by development team
exam.integration.iop.host = "http://xm.org"
# Remote reference to your organisation provided to you by development team
exam.integration.iop.organisationRef = "58a934c0e74c004753f50a9795f45327"
# Visiting examination support. true=service in use, false=service not in use
exam.integration.iop.visit.active = false
# Collaborative examination support. true=service in use, false=service not in use
exam.integration.iop.collaboration.active = false

Kun organisaatio kytketään yhteiskäyttöisyysjärjestelmään, annetaan sille tunnus, jonka avulla eri asennukset voivat kommunikoida keskenään.  Samoin yhteiskäyttöisyyspalvelimen tiedot pitää konfiguroida. Kehittäjäryhmä tarjoaa nämä tiedot sen jälkeen kun organisaatio on lisätty järjestelmään.

Omakonetenttiasetukset

Uusi toiminnallisuus, joka on vielä pilotointivaiheessa. Uusimpana asetuksena exam.byod.permission.allowed. Poistunut asetus: exam.exam.seb.quitPwd, jonka sijasta opettaja määrittelee nykyisin tenttitilaisuuskohtaisen poistumissalasanan.

Omakonetentissä opiskelija suorittaa tentin omalla tietokoneellaan tenttitilaisuudessa (rajoitettu omakonetentti) tai vapaavalintaisessa paikassa (avoin omakonetentti). Rajoitettu omakonetentti on toteutettu SEB-ohjelmistolla, joka estää tentin aikana opiskelijaa käyttämästä konettaan muuhun kuin itse EXAM-tentin tekemiseen.

Yhtäaikaa järjestettävien omakonetenttien osallistujamäärää rajoitetaan exam.byod.maxConcurrentParticipants-asetuksella. Kun tentaattori lisää EXAMiin uutta omakonetentin tilaisuutta, niin hän asettaa siinä omakonetentin maksimiosallistujamäärän. Tenttitilaisuulle asetettaavaa maksimi osallistujamäärää rajoittaa ko. exam.byod.maxConcurrentParticipants asetus sekä se jo samalle ajankohdalle EXAMissa lisättyjen muiden omakonetenttien tilaisuuksien osallistujamäärä.

Omakonetenttiin liittyviä asetuksia:

# BYOD Examination
# Enable / disable support for supervised SEB examination
exam.byod.seb.active = false
# Enable / disable support for unsupervised home examination
exam.byod.home.active = false
# Automatically grant permission to create BYOD examinations for new users with teacher role
exam.byod.permission.allowed = true
# Maximum number of concurrent BYOD examination participants
exam.byod.maxConcurrentParticipants = 100000 

# SEB configuration
#
# Encryption key for internal storage of examination event specific SEB setting passwords. Please replace with 
# something stronger.
exam.exam.seb.settingsPwd.encryption.key = "changeme"
# Link for quitting SEB after having returned the exam. Displayed for students on the EXAM UI.
exam.exam.seb.quitLink = "http://quit.seb.now"
# SEB configuration admin password. Used to protect generated SEB configuration files so that regular users can not view
# the contents using SEB configuration tool. Even if they could, modifications would not work because exam verifies that
# client's configuration is unaltered. You may also choose to use randomized admin passwords in case you wish that SEB
# configurations should not be viewed by anyone (randomize=true).
exam.exam.seb.adminPwd = { randomize = false, value = "changeme" }

Konfiguraatiotiedoston SEB configuration kohdassa on rajoitettuja omakonetenttejä koskevia asetuksia. Näistä eniten selittämistä kaipaava on rajoitetun omakonetentin lopetussalasana exam.exam.seb.quitPwd. Se on oletuksena tyhjä, mikä tarkoittaa, että rajoitetusa omakonetentissä SEB-sovelluksesta ei ole mahdollista poistua ilman että käyttäjä klikkaa EXAMin näyttämää poistumislinkkiä (exam.exam.seb.quitLink). Tämä on huijaustapausten estämiseksi kaikkein turvallisin tapa, mutta on huomioitava, että tällöin aiheutuu ongelmia koneen käytössä, jos opiskelija poistuu väkisin SEB-sovelluksesta vaikkapa buuttaamalla koneensa tai jonkun muun ongelman seurauksena. Jos halutaan että esimerkiksi tentin valvoja voi manuaalisesti päättää opiskelijan SEB-session, voidaan siihen tarkoitukseen käyttää salasanaa, mutta on huomioitava että sen on syytä pysyä tiukasti pelkästään virkalijoiden ja ylläpitäjien tietona. Jatkossa mietitään otetaanko käyttöön tenttitilaisuuskohtainen poistumissalasana, joka olisi tietoturvan kannalta huomattavasti parempi ratkaisu, mutta lisäisi toki byrokratiaa opettajan päässä.

Opintojaksokoodien osien piilottaminen tietyn merkin jälkeen

Erityisesti Sisu-opintotietojärjestelmäsä tuotujen opintojaksojen/toteutusten koodien osien piilottamiseen toteutettu ominaisuus. Sisusta tulevat koodit saattavat olla pitkiä tyyliin GEOK-2032_otm-3100f0b7-1826-4688-b6c8-96efc37bff0a. Näissä EXAMin käyttäjille merkitsevä osuus on alussa oleva GEOK-2032, joten sen jälkeistä pitkää merkkijonoa ei haluta näyttää EXAMin käyttöliittymässä kohdissa missä koodia esitetään. Nyt konfiguraatiotiedostossa voidaan määritellä merkki (oletuksena: "_"),  jonka (viimeisen esiintymän) jälkeistä osaa ei näytetä EXAMin käyttöliittymällä. Edellisen esimerkin koodista näytetään käyttöliittymällä GEOK-2032- Jos Sisusta tuleva koodi olisi MATH_1234_atb-098876-234-123-456-678, niin tästä koodista näytetään EXAMin käyttöliittymällä viimeistä _ -merkkiä edeltävä osuus MATH_1234. Jos ei ole tarvetta piilottaa osia opintojaksokoodeista, niin ko. asetus jätetään tyhjäksi.


# Prefix to use with courses' internal code that needs to be hidden from users. Leave empty if your course integration
# does not have any internal codes that it sends.
exam.course.code.prefix = "_"

Examin käynnistys

Examin voi käynnistää joko palveluna (yleisin käyttötapaus) tuotantomoodissa tai kehitysmoodissa sbt-konsolissa. On huomioitava, että postgresql, apache ja shibd ovat käynnistetty ennen examin tuotantokäynnistystä. Lisätietoa Play-applikaatioiden ajamisesta tuotantoympäristössä: https://www.playframework.com/documentation/3.0.x/Production

Käynnistys palveluna

Paketoi käyttöliittymän lähdekoodi npm-työkalulla lähdekoodihakemistossa.

$ sudo -u exam npm install
$ sudo -u exam npm run-script build

Tämä pakkaa examin käyttöliittymän lähdekoodin hakemistoon ./public, josta se on exam-applikaation käytettävissä.

Paketoi seuraavaksi palvelimen lähdekoodi.

$ sudo -u exam sbt clean stage
...
[info] Done packaging.
[success] Total time: 34 s, completed Mar 1, 2024 10:27:16 AM

Samalla SBT luo Playn kännistysskriptin ja muut tarvittavat tiedostot hakemistoon ./target/universal/stage. Automaattisesti luotu käynnistysskripti löytyy tämän jälkeen paikasta ./bin.

Helpointa on kuitenkin käyttää seuraavantyyppistä systemd-skriptiä:

/etc/systemd/system/exam.service
[Unit]
Description=Exam service

[Service]
ExecStart=/opt/exam/exam/target/universal/stage/bin/exam -Dplay.evolutions.db.default.autoApply=true -Dplay.evolutions.db.default.autoApplyDowns=true -Dconfig.file=/opt/exam/exam/conf/application.conf -J-Xmx2048M
User=exam
Group=exam

[Install]
WantedBy=multi-user.target

Jos haluat allokoida EXAM:n JVM-prosessille lisää muistia tai muuten muuttaa JVM:n parametreja, löytyy apua tästä osoitteesta: https://www.playframework.com/documentation/3.0.x/ProductionConfiguration#JVM-configuration. Jos vaikkapa halutaan kasvattaa JVM:n heap-kokoa, vaihdetaan ylläolevaan komentoon -J-Xmx4096M.

Riippuen käyttöjärjestelmästä käynnistyskriptin käyttö tapahtuu jotenkin näin:

$ sudo systemctl enable exam.service
$ sudo systemctl start exam.service // tai stop/restart/status

Käyttö kehitysmoodissa

Examin palvelimen voi käynnistää kehitysmoodissa sbt-konsolissa komennolla run. Tällöin ei tarvitse käyttää apachea tai shibbolethia.

$ sudo -u exam sbt -Dconfig.resource=dev.conf -mem 2048 -v
...
started sbt server
[exam] $ run
...
--- (Running the application, auto-reloading is enabled) ---

INFO  p.c.s.PekkoHttpServer - Listening for HTTP on /[0:0:0:0:0:0:0:0]:9000

(Server started, use Enter to stop and go back to the console...)

Tällöin asetustiedostossa pitää muuttaa  exam.login="HAKA" -> exam.login="DEBUG". Tällöin myös käyttäjät, käyttäjäroolit sekä md5-enkoodatut salasanat tulee olla lisättynä manuaalisesti examin-tietokantaan.

Käyttöliittymäsovellus käynnistetään kehitysmoodissa näin. Tämä avaa porttiin 4200 proxyn, joka välittää selaimesta kutsut palvelimelle ja päinvastoin. Pääset sovellukseen siis selaimesta osoitteessa localhost:4200.

$ sudo -u exam npm install
$ sudo -u exam npm start

Integraatiotestit voidaan ajaa sbt-konsolissa kommennolla test. Tätä ennen testitietokannan tulee olla luotuna (katso Tietokanta).

$ sudo -u exam sbt
...
started sbt server
[exam] $ test
...
[info] Passed: Total 74, Failed 0, Errors 0, Passed 72, Skipped 2
[success] Total time: 307 s, completed Oct 10, 2017 3:35:38 PM

Maturiteetti eli kypsyysnäyte ja kielentarkastus

Maturiteetti eli kypsyysnäyte tenttityypin käyttöönotto tapahtuu tietokannassa lisäämällä se tuettujen suoritustyyppien joukkoon:

$ psql -Uexam exam

exam=> insert into exam_execution_type values (3, 'MATURITY', 'Examination with language inspection process');
INSERT 0 1
exam=> \q

Maturiteettiohjeet syötetään niinikään tietokantaan (niin kauan kun muuta käyttöliittymää ei tätä varten ole) relaatioon general_settings seuraavin tiedoin:

  • id: seuraava vapaa id taulussa
  • object_version: 1
  • namematurity_instructions_xx missä xx joku seuraavista: fi, sv, en
  • value: varsinainen ohje name-kohdassa määritellyllä kielellä. Voi sisältää html:ää.

Eli esimerkiksi ruotsinkielinen maturiteettiohje lisätään näin:

$ psql -Uexam

exam=> insert into general_settings (id, object_version, name, value) values (4, 1, 'maturity_instructions_sv', '<p>Instruktioner på svenska</p>');

Tulostettava tentti (deprecated)

Tulostettava tentti -tenttityyppi ei ole tuettu EXAMin 6.1 versiosta alkaen. Uusien tenttimispäivien lisääminen ei enää onnistu, joten uusia tulostettavia tenttejä ei pysty julkaisemaan eikä vanhoihin tentteihin pysty lisäämään uusia tenttimispäiviä. Tulostettavien tenttien esikatselu ei myöskään toimi oikein.

Jos Tulostettava tentti -tenttityyppi on otettu EXAMissa käyttöön, niin sen saa pois käytöstä seuraavasti:

$ psql -Uexam exam 

exam=> update exam_execution_type set active = false where id = 4;

Kun Tulostettava tentti on otettu pois käytöstä, niin uusia tulostettavia tenttejä ei pysty enää luomaan EXAMiin. Vanhat tulostettavat tentit näkyvät EXAMissa edelleen tentaattoreille ja ylläpitäjille.


Tulostettava tentti otetaan käyttöön samaan tapaan kuin maturiteetti:

$ psql -Uexam exam

exam=> insert into exam_execution_type values (4, 'PRINTOUT', 'Paper exam. No enrolment or review process included');

INSERT 0 1 exam=> \q

Pääkäyttäjien lisääminen

Jos ja kun pääkäyttäjän roolin omaavia käyttäjiä ei voda suoraan tuoda HAKA:sta, täytyy käyttäjäroolin korotus tehdä käsin. Käyttäjän, josta halutaan pääkäyttäjä, täytyy ensin kirjautua EXAMiin HAKA-roolissansa. Tämän jälkeen tietokannassa korotetaan roolia vaikkapa näin:

$ psql -Uexam exam

exam=> update app_user_role set role_id = (select id from role where name = 'ADMIN') where app_user_id = (select id from app_user where eppn = 'USER_EPPN');
UPDATE 1
exam=> \q

Korvaa ylläoleva USER_EPPN kyseisen käyttäjän eppn-tunnisteella. Kun käyttäjä seuraavan kerran kirjautuu EXAMiin, kirjautuu hän pääkäyttäjän roolissa.

Käyttäjien rooleja voi ylläpitäjä määritellä myös examin selainkäyttöliittymän kautta.

Tenttimiskielten muokkaus

Oletuksena EXAMissa on määritelty neljä tuettua tenttimiskieltä, joista opettaja voi valita tenttiä luodessaan: suomi, ruotsi, englanti ja saksa. Nämä ovat ne kielet joilla opiskelijan on katsottu olevan mahdollista suorittaa tentti. Järjestelmään on mahdollista lisätä tai poistaa kieliä muokkaamalla tietokannan relaatiota language. Tietenkään poistaminen ei onnistu noin vain, jos kieli on jo jossain tentissä käytössä. Kielet identifioidaan ISO-639_1-koodin mukaan. Käytännössä kolumnilla name ei ole merkitystä vaan toimii ainoastaan selitteenä tietokannassa.


exam=> select * from language;
 code |   name   | object_version
------+----------+----------------
 fi   | Suomi    |              1
 sv   | Ruotsi   |              1
 en   | Englanti |              1
 de   | Saksa    |              1
(4 rows)


exam => delete from language where code = 'de';
DELETE 1
exam => insert into language values ('es', 'Espanja', 1);
INSERT 0 1

Logitiedot

EXAMin logit kirjautuvat oletuksena tiedostoon /var/log/exam/application.log. Logia voi kätevästi seurata reaaliajassa esimerkiksi komennolla

$ tail -f -n 100 /var/log/exam/application.log

Logituksen asetuksia voi muokata asetustiedostosta. Ohjeet tähän löytyvät Playn sivuilta: https://www.playframework.com/documentation/3.0.x/SettingsLogger

Järjestelmän päivittäminen

Kun järjestelmää päivitetään, on syytä ottaa huomioon ainakin seuraavat asiat.

Ota varmuuskopiot ainakin seuraavista:

  • hakemisto, joka sisältää examin hallinnoimat liitetiedostot
  • käytettävä konfiguraatiotiedosto application.conf tai muu
  • tietokantadumppi ennen päivitystä
  • mahdolliset omat lähdekoodien kustomoinnit (ks. mm. alla)

Lokalisointi

Examin lokalisointi tapahtuu kahdessa paikassa

  1. Käyttöliittymän lokalisointitiedostot sijaitsevat hakemistossa /ui/src/assets/i18n json-tiedostojen muodossa. Tiedostoja on yksi per tuettu kieli ja sisältö on tämän suuntainen

    fi.json
    {
      "i18n_abort_exam": "Keskeytä tentin suoritus",
      "i18n_accept_useragreement": "Käyttäjäehtojen hyväksyminen.",
      "i18n_active_exams": "Opiskelijoille näkyvät tentit",
       ...
    } 

    eli se sisältää listauksen käännöksen tunnisteesta ja varsinaisesta käännöstekstistä. Näihin tiedostoihin sisältyy ylivoimaisesti suurin osa järjestelmän lokalisoinnista.

  2. Palvelimen lokalisointitiedostot sijaitsevat tiedostoissa /conf/messages.xx. missä xx on kielikoodi. Tiedostoja on yksi per tuettu kieli ja sisältö on tämän suuntainen

    messages.fi
    email.inspection.ready.subject=Tenttivastauksesi on arvioitu
    email.inspection.comment.subject=Tenttisuorituksen arviointiin on lisätty kommentti
    email.enrolment.no.reservation=HUOM! Et ole vielä varannut tenttiaikaa tenttitilasta
    ...

    Kyseisiä käännöksiä tarvitaan lähinnä järjestelmän lähettämissä sähköpostiviesteissä sekä jossain EXAMin generoimissa raporteissa.

Näitä voi kustomoida mielensä mukaan, muutosten jälkeen exam pitää paketoida ja käynnistää uusiksi (ks: Examin käynnistys). Päivitettäessä Examin lähdekoodeja versionhallinnasta on odotettavissa merge-konflikteja, jos lokalisointitiedostoja on kustomoitu. Konfliktit on itse ratkottava siten että lopputuloksena tiedosto on halutunlainen. Ohjeita editointikonfliktin ratkomiseen löytyy esim. tästä: https://help.github.com/articles/resolving-a-merge-conflict-from-the-command-line/.

Selainyhteensopivuudesta

Suosittelemme jo tietoturvasyistäkin päivittämään ainakin tenttitilojen selaimet vähintään parin vuoden välein tai vaihtoehtoisesti niin sanottuihin pitkän ajan tuen versioihin (LTS), sillä emme voi taata täyttä tukea kovin vanhoille selainversioille. Tämä johtuu selain- ja ohjelmistoteknologian kehityksen nopeasta tahdista ja olemme jossain määrin sidottuja käyttämämme Angular-kehyksen asettamiin raja-ehtoihin. Angularin sivuilta löytää tarkempia tietoja asiasta, käytämme samoja oletusasetuksia ainakin toistaiseksi ellei muuta toivota. On huomioitava, että tukeaksemme vanhempia selaimia, tarkoittaisi se myös sitä, että selaimeen joka kerta ladattavan ohjelmiston koko kasvaa ja sillä on tietysti merkitystä latausaikoihin ja tiedonsiirron määriin.



  • No labels