Versioon Autor Kuupäev Märkused 1.0 Riivo Talviste 03.03.2008 Algdokument 1.1 Riivo Talviste 04.04.2008 Arhitektuurimuutused, terminoloogia 1.2 Riivo Talviste 05.04.2008 Arhitektuuri täpsustused, parandused 1.3 Riivo Talviste 05.04.2008 Võtmete täpsustus 1.4 Riivo Talviste, Gert Palok 13.04.2008 Füüsiline arhitektuur 1.5 Riivo Talviste, Gert Palok 14.04.2008 Pärningu JSON formaadi kirjeldus 1.6 Riivo Talviste, Gert Palok 12.05.2008 JSON formaadi täiendused Sisukord Arhitektuuridokument Sissejuhatus 2 1 Loogiline arhitektuur 2 1.1 Terminoloogia.................................. 2 1.2 Andmekiht.................................... 2 1.3 Teenuseliides.................................. 3 1.4 API....................................... 4 1.5 Kasutajarakendus................................ 4 2 Füüsiline arhitektuur 4 2.1 Platvormisõltumatus.............................. 4 2.2 Skaleeritavus.................................. 5 3 Tehnoloogiad 5 3.1 Kasutatavad tehnoloogiad........................... 5 3.2 Arendusvahendid................................ 5 4 Lisa 1. Päringu JSON formaat 6 4.1 Objekti küsimise formaat............................ 6 4.2 Navigatsiooni päringu formaat......................... 6 5 Lisa 2. Vastuse JSON formaat 7 5.1 Objekti vastuse formaat............................ 7 5.2 Navigatsiooni vastuse formaat......................... 7 1
Sissejuhatus Käesolev dokument kirjeldab Delfi WhatsOn projekti arhitektuuri. Järgnevas tuuakse antud süsteemi osade - teenuse, andmekihi ja API - lühike kirjeldus ning nõuded, millele need vastama peavad. Samuti esitatakse juhtnöörid kliendirakendusele, mis seda API-t kasutab. Viimaseid järgib ka antud projekti juurde kuuluv näiteklient. 1 Loogiline arhitektuur 1.1 Terminoloogia Käesolevas dokumendis kasutatakse järgmist sõnavara: Delfi klient, kes tellis antud projekti (peamiselt API); klient Delfi klient, kes hakkab kasutama projekti käigus valmivat API-t, et pääseda ligi Delfi WhatsOn teenusele. Muuseas on ka delfi iseenda klient, kuna kasutab antud API-t portaalis kuhuminna.delfi.ee; kasutaja, lõppkasutaja klientide klient; kasutaja, kes pääseb ligi mõnele veebilehele, mis kasutab antud API-t. objekt inglise k. object. Sisulist mõtet omav sissekanne, millel on erinevad atribuudid. Eristatakse kolme tüüpi objekte: sündmused (event), kohad (place) ja huvitegevused (hobby). kategooria inglise k. facet. Objekti atribuut, mis on määratud kategooriaks ja mille järgi on võimalik otsingutulemusi kitsendada (filtreerida). 1.2 Andmekiht Delfi on jaotanud oma andmed suures osas kaheks: publitseeritud andmed (published events) ning arhiiv (archive), mis asuvad kumbki eraldi MySQL andmebaasides. Publitseeritud andmeid on vaid need andmed, mis on lõppkasutajale nähtavad, modereerimisele ja arhiveerimisele kuuluvaid andmeid hoitakse arhiivandmebaasis. Antud projektile on olulised just publitseeritud andmed. Kuna antud andmebaasile tehtavate päringute hulk ületab tunduvalt lisamise või muutmise päringute hulga, siis on andmemudel optimeeritud just päringute tegemisele, eriti hierarhiliste andmete saamiseks. Andmemudelis on realiseeritud järgmised nõuded: 2
hierarhilised andmed (Näiteks Pärnumaa Pärnu. Kõik sündmused, mis toimuvad Pärnus, toimuvad ka Pärnumaal) hierarhilised kategooriad (Sarnaselt eelmisele Maakond Linn Linnaosa, kusjuures Linnaosa Linn Maakond) kliendipõhised juurdepääsu õigused st. klient saab otsingutulemusena näha vaid neid atribuute, millele tal on juurdepääs. mitmekeelsus - kõik sõned (k.a. kategooriate ja atribuutide pealkirjad) on andmebaasis mitmes eri keeles. Tõlkeid erinevatesse keeltesse saab vajadusel lisada/eemaldada. ühel sündmusel saab olla mitu toimumiskohta ja -perioodi (korduvad ja perioodilised üritused) Kliendipõhised atribuutide juurdepääsu õigused on realiseeritud võtmetega - iga klient saab omale unikaalse võtme, mille ta API kaudu iga päringuga kaasa saadab. Päringu tulemusena saadetakse kliendile tagasi tulemuste nimekiri, kus on vaid need objektide atrubuudid, mida antud võtmega näha saab. Atribuudid, mis pole seotud ühegi kliendi võtmega, on kõigile nähtavad. Andmemudeli juurde kuulub ka Andmemudeli struktuuridokument, milles kirjeldatakse täpselt andmemudeli ülesehitus ja formaat, mida sisendandmed järgima peavad. Andmemudelite graafilised esitused on saadaval eraldi UML diagrammidena: wo2-datamodel-facets.png wo2-datamodel-i18n.png wo2-datamodel-acl.png wo2-datamodel-periods.png Arhiivandmebaasi ja administreerimisliidese realiseerimine on väljaspool selle projekti skoopi, need teeb Delfi ise. Samuti hoolitseb Delfi andmete paigutamisest publitseeritud andmete andmebaasi, järgides eelpool mainitud dokumendis kirjeldatud reegleid. 1.3 Teenuseliides Kuna üheks nõudmiseks on kliendipõhise juurdepääsu tagamine, siis ei ole võimalik andmebaasiga otsesuhtlust viia kliendi juurde, sest sel juhul saaks sellest mööda hiilida. Selle vältimiseks asub Delfi juures teenus (service), mille ülesandeks on vastu võtta kliendi poolt saadetud päring, konstrueerida sellest SQL päring ning saata tulemused tagasi kliendile. Tulemused koosnevad järgmistest osadest: päringitingimustele vastavad objektid koos atribuutidega, mida näidatakse tulmuste tabelis; kõik kategooriad koos nende elementidega, kusjuures iga elemendi juurde on märgitud arv, mis näitab, mitu tulemust tagastataks, kui see element valida. Antud liides on realiseeritud PHP keeles ja kasutab andmebaasiga suhtluseks mysqli moodulit. Kliendiga toimub suhtlus JSON (Javascript Object Notation) formaadis üle HTTP protokolli. Teenuse ja kliendi vaheliste päringute JSON formaat on kirjeldatud antud dokumendi lõpus asuvates lisades. 3
1.4 API API (Application Programming Interface) ülesandeks on pakkuda klientrakendusele meetodeid, mille abil saab teenuseliidesega suhelda esitada päringuid ja tulemusi. Päringuid on kahte liiki: otsimine märksõna järgi ning otsingutulemuste kitsendamine kategooriate põhjal. Neid päringuid on võimalik omavahel ka kombineerida (kokku konjugeerida) st. on võimalik sooritada kõigepealt märksõna otsing ning seejärel selle tulemusi kitsendada, valides kategooriatest täpsustavaid parameetreid. Loomulikult on võimalik ka vastupidine: kõigepealt kitsendada tulemusi ning seejärel lisada märksõna otsing (kuna konjunktsioon on kommutatiivne). Lisaks sellele on API kaudu võimalik teenuse käest küsida konkreetset objekti st. kogu väärtuste hulka, mis kuuluvad selle konkreetse objekti juurde. API realiseeritakse PHP keele abil ning suhtlus teenuseliidesega toimub JSON formaadis. Lisaks päringumeetodite pakkumisele on API ülesandeks veel teenuseliideselt saadud JSON -formaadis vastuse parsimine objektideks (üritused, kohad, atribuudid), et kasutajarakendus saaks neid mugavalt kasutada. 1.5 Kasutajarakendus Kasutajarakendus (client side business logic) koosneb soovitatavalt vähemalt kahest osast: vaatest ja loogikast. Rakenduse loogika osa põhiülesandeks on API-ga suhtlemine ning vaate kontrollimine. Selleks realiseerib viimane järgmised ülesanded: annab API-le ette otsinguparameetrid ja kategooriad, kasutades selleks konjunktiivset normaalkuju (PHP-s kasutatkse selleks massiivide hierarhiat); otsustab, milliseid kategooriaid ja mis järjekorras kliendile näidata; kasutab API poolt tekitatud objekte, et koostada kasutajavaade. Rakenduse vaate osa hoolitseb kasutajale nähtava veebilehe kujunduse eest. Antud projekti käigus valmiv näidis kasutajarakendus realiseerib vaid olulisemad osad Nõuetedokumendis kirjeldatud funktsionaalsusest: Otsing märksõna järgi Otsingutulemuste kitsendamine erinevate kategooriate järgi Näiteks: Tartu kontsert Otsingutulemuste kitsendamine kategooria mitme erineva elemendi järgi Näiteks: Tartu + Pärnu kontsert Kategooriate ja nende elementide nimekirja väljastamine Konkreetse ürituse või koha kuvamine Näidisrakenduse loogika kirjutatakse keeles PHP ning XHTML standardile vastav vaade luuakse Smarty mallide abil. 2 Füüsiline arhitektuur 2.1 Platvormisõltumatus Kuna antud projekt kasutab kõikides kihtides tehnoloogiatena PHP-d ja MySQL-i, siis on see ka platvormist sõltumatu. Andmebaasi, teenuse ja API töölesaamiseks on vaja järgida Installatsioonijuhendis esitatud nõudmisi. 4
2.2 Skaleeritavus Projekti üheks peamiseks eesmärgiks on valmiva süsteemi skaleeritavus. Seepärast on lisaks andmemudeli paindlikkusele mõeldud ka füüfilisele skaleeritavusele - võimalik on kasutada MySQL andmebaaside klasterid (MySQL Cluster) või replikeerimist (MySQL Replication). Kuna vastavate süsteemide ülesseadmine ei kuulu antud projekti skoopi, siis on viidatud nende kasutusjuhenditele: MySQL Cluster: http://dev.mysql.com/tech-resources/articles/mysql-cluster-for-two-servers.html MySQL Replication: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html 3 Tehnoloogiad 3.1 Kasutatavad tehnoloogiad Nimetus Kodulehekülg Eesmärk PHP 5.1.6 http://php.net/ Arenduskeel, muuhulgas sisaldab mysqli moodulit MySQL 5.0.22 http://mysql.com/ Andmebaasisüsteem Smarty 2.6.19 http://www.smarty.net/ Kasutajarakenduse vaate mallid 3.2 Arendusvahendid Järgnevas mainitud tehnoloogiad pole vajalikud projekti tulemuse kasutamiseks, vaid on seotud selle arendamisega. Nimetus Kodulehekülg Eesmärk Subversion 1.4.2 http://subversion.tigris.org/ Koodi versioonihaldus Apache Ant 1.7.0 http://ant.apache.org/ Ehitusskriptid Changelogic http://www.changelogic.com/ Vigade ja ülesannete halduskeskkond phpdocumentor 1.4.2 http://www.phpdoc.org/ Dokumentatsiooni genereerimine lähtekoodist 5
4 Lisa 1. Päringu JSON formaat 4.1 Objekti küsimise formaat "language":1, // Keele ID "key":"xvvotrbxxo0y2wh4b48uzjlhtfmcl7ky", // Kliendi v~oti "action":"view", // Tegevus: vaatamine "id":10556 // Päritava objekti ID 4.2 Navigatsiooni päringu formaat "language":1, // Keele ID "key":"client s secret key", // Kliendi v~oti "keyword":["otsis\u00f5na", // Massiiv otsingus~onadest "filters":[ // Kasutaja valitud facetite väärtused "id":1, // Facetile vastava atribuudi ID 2 // Massiiv selle atribuudi väärtuste ID-dest, // mille järgi klient on kitsendanud, "id":3, 1,4, "facetattributes":[1,2,3,4, // Nende atribuutide ID-d, mida soovitakse // facetitena tagasi saada. V~oib olla ka // tühi massiiv. "facetattributescmpl":true, // T~oeväärtus, kas saata facetattributes // massiivis olevad atribuudid v~oi // hoopis selle hulga täiend. "resultattributes":[1,3, // Massiiv nende Atribuutide ID-dest, mida // tahetakse tulemusobjektidega kaasa saada. // V~oib olla ka tühi massiiv. "resultattributescmpl":true, // T~oeväärtus, kas saata resultattributes // massiivis olevad atribuudid v~oi // selle hulga täiend. "order":[ // Sorteerimisvektor. [2,true // Massiiv massiividest, mille elementideks on atribuudi // ID, mille järgi sorteerida ja t~oeväärtus, kas sorteerida // kasvavalt v~oi mitte., "start":0, // Esimese tagastatava kirje järjekorranumber. // Lugemist alustatakse 0-st. "limit":50 // Arv, mitu kirjet tulemustena tagastada. 6
5 Lisa 2. Vastuse JSON formaat 5.1 Objekti vastuse formaat Objekti küsimisel tulnud vastuse formaat on väga sarnane allpool toodud navigatsiooni vastuse formaadile, seepärast on siin toodud ainult fragment sellest formaadist: [ true, // Päringu ~onnestumise näitaja. Kui see on väär, siis sellele // järgnev JSON object on erindi info. "attributes":[ // Atribuutide massiiv, samasuguse ülesehitusega... // nagu navigatsiooni vastuse korral., "properties":[ // Objekti omaduste massiiv. Samasuguse ülesehitusega // nagu navigatsiooni puhul iga tulemuse omaduste massiiv. "id":123, // Erinevalt navigatsiooni tulemustest on siin igal // omadusel ka ID. "attribute":5, // Tekstilised väärtused on otse s~onena: "value":"p\u00e4rnu Vanalinna P\u00f5hikooli luulev\u00f5istlus", "id":567, "attribute":1, "value":15 // Diskreetsetel väärtustel on vastava väärtuse ID, 5.2 Navigatsiooni vastuse formaat [ true, // Päringu ~onnestumise näitaja. Kui see on väär, siis sellele // järgnev JSON object on erindi info. "attributes":[ // Atribuutide massiiv "id":1, // Atribuudi ID andmebaasis "type":"discrete", // Atribuudi tüüp "title":"t\u00fc\u00fcp", // Atribuudi pealkiri (valitud keeles) // Atribuudi väärtused "id":13, "title":"kontsert", 7
"id":14, "title":"etendus", "id":15, "title":"v\u00f5istlus", "id":100, "type":"discrete", "title":"objekti t\u00fc\u00fcp", "id":1, "title":"event", "id":2, "title":"place", "id":3, "title":"hobby", "id":2, "type":"object", "title":"toimumiskoht", "id":3, "type":"discrete", "title":"koht", "categories":[ // Hierarhiliste atribuutide korral on kategooriad "id":1, "title":"maakond", "id":2, "title":"linn", "parent":1 // Hierarhias samm k~orgemal asuva kategooria ID, 8
"id":3, "title":"linnaosa", "parent":2, "id":1, "title":"p\u00e4rnumaa", "category":1 // Kategooria ID, "id":2, "category":2, "title":"p\u00e4rnu", "parent":1 // Hierarhias samm k~orgemal asuva väärtuse ID, "id":3, "category":3, "title":"kesklinn", "parent":2, "id":4, "title":"sindi", "parent":1, "id":5, "category":1, "title":"tartumaa", "id":4, "type":"period", "title":"toimumisaeg", "id":21, "title":"t\u00e4na", "id":22, "title":"homme" 9
, "id":5, "type":"text", "title":"pealkiri", "id":6, "type":"text", "title":"esineja", "id":31, "title":"dag\u00f6", "id":32, "title":"t\u00f5nis M\u00e4gi", "facets":[ // Valitavad facetid "attribute":3, // Vastava atribuudi ID "id":1, "hits":22 // Selle väärtuse valimisel allesjäävate // tulemuste arv, "id":5, "hits":35, "attribute":1, "id":13, "hits":12, "id":14, "hits":6 10
, "attribute":4, "id":21, "hits":10, "id":22, "hits":12, "attribute":6, "id":31, "hits":2, "id":32, "hits":1, "results":[ // Tulemused "id":1, "properties":[ // Tulemuse omadused "attribute":5, // Tekstilised väärtused on otse s~onena: "value":"p\u00e4rnu Vanalinna P\u00f5hikooli luulev\u00f5istlus", "attribute":1, "value":15 // Diskreetsetel väärtustel on vastava väärtuse ID, "attribute":2, "value":666, 11
"attribute":4, "value": "begin":1208125639, // Perioodidel on algus- ja l~oppaeg "end":1208125879, "attribute":100, "value":1, "id":2, "properties":[ "attribute":5, "value":"kevadkontsert", "attribute":1, "value":13, "attribute":2, "value":123, "attribute":4, "value": "begin":1208126959, "end":1208126959, "attribute":6, "value":"dag\u00f6", "attribute":6, "value":"t\u00f5nis M\u00e4gi", "attribute":100, "value":1 12
13