Platforma online pentru învățare [304346]

Platforma online pentru învățare

PROIECT DE DIPLOMĂ

Autor: Darius Ovidiu CUPȘA

Conducător științific: S.I.dr.ing. Mihai HULEA

Autor: Darius Ovidiu CUPȘA

Platforma online pentru învățare

Enunțul temei: Proiectul își propune implementarea unei aplicații web pentru accesarea de materiale didactice online.

Conținutul proiectului:

Pagina de prezentare

Declarație privind autenticitatea proiectului

Sinteza proiectului

Cuprins

1. Introducere

2. Obiective și specificația proiectului

3. Studiu bibliografic

4. Analiză și proiectare

5. Implementare

6. Testare și validare

7. Concluzii

Bibliografie

Acronime

În primul capitol se prezintă contextul proiectului cât și tema lucrării.

În capitolul doi se prezintă obiectivele proiectului și cele două tipuri de specificații: [anonimizat].

În capitolul trei se prezintă un scurt studiu bibliografic despre arhitecturile utilizate: REST, Three-Tier și Flux.

Capitolul patru prezintă partea de analiză și fundamentare teoretică.

În capitolul cinci sunt prezentate detalii legate de proiectarea și implementarea sistemului: [anonimizat], [anonimizat].

În capitolul șase se prezintă modalitățile de testare și validare a componentelor aplicației.

Capitolul șapte prezintă concluziile proiectului cât și sugestii pentru dezvoltări ulterioare.

Locul documentației: [anonimizat]: S.I.dr.ing. Mihai HULEA

Data emiterii temei:

Data predării:

Semnătura autorului

Semnătura conducătorului științific

Declarație pe proprie răspundere privind

autenticitatea proiectului de diplomă

Subsemnatul(a) [anonimizat](ă) cu CI/BI seria CJ nr. 201337 , CNP [anonimizat] ,

autorul lucrării:

Platforma online pentru învățare

elaborată în vederea susținerii examenului de finalizare a [anonimizat] ,

[anonimizat],

sesiunea a anului universitar 2016-2017,

[anonimizat], [anonimizat], și în bibliografie.

Declar, [anonimizat] a convențiilor internaționale privind drepturile de autor.

Declar, [anonimizat] a mai fost prezentată în fața unei alte comisii de examen de licență.

In cazul constatării ulterioare a [anonimizat], respectiv, anularea examenului de licență.

Data Prenume NUME

(semnătura)

SINTEZA

proiectului de diplomă cu titlul:

Platforma online pentru învățare

Autor: Darius Ovidiu CUPȘA

Conducător științific: S.I.dr.ing. Mihai HULEA

1. Cerințele temei:

Implementarea unei aplicații web pentru accesarea de materiale didactice online.

2. Soluții alese:

Sistemul este format din trei aplicații cu funcții specifice dezvoltate independent. [anonimizat], [anonimizat] a sistemului.

[anonimizat]irii sistemului fiind create câteva scripturi.

3. Rezultate obținute:

Printre principalele specificații realizate reamintim: managementul utilizatorilor, adăugarea și modificarea categoriilor de materiale cât și a lecțiilor apartenente acestora, posibilitatea creării de sesiuni de predare în cadrul clasei virtuale unde participanții au acces la câteva unelte de desen cât și un chat în timp real.

4. Testări și verificări:

Pentru testarea aplicațiilor server s-a folosit Postman, pentru testarea proxy-ului și a load-balancer-ului s-a utilizat Apache Benchmark, iar pentru testarea componentei web s-a folosit BrowserStack.

5. Contribuții personale:

Implementarea celor trei componente ale sistemului cât și proiectarea infrastructurii pe care rulează.

6. Surse de documentare:

Cursuri, internet.

Semnătura autorului

Semnătura conducătorului științific

Introducere

Contextul proiectului

Privind în jur nu putem să nu realizăm că trăim într-o lume din ce în ce mai tehnologizată. Activitățile în mediul online cresc exponențial de la o zi la alta, ridicând gradul de confort al consumatorului, iar împreună cu această creștere și percepția noastră cu privire la trecerea timpului se schimbă.

Astfel, privim cu o mai mare rigoare pierderea fără de folos a timpului în trafic și în alte conjuncturi alegând de cele mai multe ori să căutăm materiale informative în spațiul online. Cu această schimbare de percepție, în ultimul deceniu au apărut într-un ritm constant platforme noi cu materiale didactice facilitând dezvoltarea personală și profesională a consumatorului.

Printre avantajele acestei abordări asupra educației se numără:

Posibilitatea învățării continue

Alegerea ritmului de studiu

Oferta de materiale didactice este mult mai diversificată în comparație cu educația tradițională

Costuri mult mai reduse

Tema lucrării

Principalul obiectiv al acestui sistem este de a facilita accesul la materiale didactice, cât și la sesiuni de predare cu profesori acreditați într-un mediu virtual.

Pentru îndeplinirea acestui scop, sistemul pune la dispoziția utilizatorilor o aplicație web ce rulează în majoritatea browserelor moderne. În momentul în care un utilizator accesează aplicația, acestuia îi va fi prezentat un formular de autentificare. Pe baza informațiilor primite după autorizarea utilizatorului în aplicație acesta va avea acces la materiale didactice bine pregătite cât și la sesiuni de predare în timp real cu profesori acreditați.

Trăind într-o lume digitalizată, educația online prezintă una dintre opțiunile principale ale tinerilor și nu numai din întreaga lume, oameni care muncesc, care se pot implica în alte proiecte profesionale și personale, privilegiind astfel și educația în același timp.

Condiția necesară utilizării acestui sistem este deținerea unor dispozitive care să poată susține infrastructura necesară rulării componentelor principale, fiind indicat un server care să ruleze Linux și să fie conectat la internet. Fiecare utilizator va avea nevoie de un calculator cu acces la internet, un browser relativ modern și url-ul unde serverul este hostat.

Obiectivele și specificațiile proiectului

Obiectivele proiectului

Scopul acestei aplicații este acela de a facilita comunicarea dintre profesor și elevi cât și oferirea unei platforme pentru susținere a cursurilor în mediul online.

Principalele funcționalități implementate sunt următoarele:

Funcționalități generale

Logarea în aplicație folosind adresa de email și parola

Vizualizarea claselor în care aparții și a sesiunile aferente acestora

Accesarea clasei virtuale

Listă cu participanții care au accesat aceeași clasă virtuală

Chat în timp real cu participanții din sesiunea curentă

Vizualizarea unei lecții în cadrul clasei virtuale

Utilizarea diferitelor unelte de desen (creion, dreptunghi, linie, marker, radieră)

Funcționalități specifice profesorilor

Adăugare de noi studenți și asignarea acestora în clase virtuale

Adăugarea și modificarea claselor virtuale

Adăugarea și modificarea sesiunilor aferente

Adăugarea de categorii de materiale

Adăugarea de materiale in diferite categorii

Funcționalități specifice administratorilor

Adăugare de noi profesori

Specificațiile proiectului

Specificații funcționale

Logarea în aplicație folosind adresa de email și parola

Mecanismul de logare se va realiza în felul următor: când utilizatorul va accesa platforma, acestuia i se va prezenta un formular de logare cu email și parolă. După completarea acestor informații, ele vor fi transmise serverului care le va verifica și va genera un token (JSON Web Token) valid pe baza datelor de autentificare primite, token ce va fi utilizat mai apoi de platformă pentru toate request-urile ce vor urma.

Vizualizarea claselor în care aparții și a sesiunilor aferente acestora

După autentificare, utilizatorul (fie el elev, profesor sau administrator) va fi redirecționat către un panou de control unde va putea vedea trei tabele:

Clase virtuale din care faci parte (la care predai)

Sesiuni precedente

Sesiuni viitoare

Accesarea clasei virtuale

Din panoul de control, utilizatorul va putea accesa clasa virtuală, pentru sesiunile precedente și pentru cele viitoare doar dacă data de început a sesiunii este mai mică sau egală cu data curentă, printr-un simplu click pe linkul aferent sesiunii.

Lista cu participanții care au accesat aceeași clasă virtuală

Când o sesiune este deschisă în clasa virtuală, aceasta se conectează la un server de tip socket (timp real), trimite token-ul primit la autentificare si id-ul sesiunii creând astfel un canal de comunicare in timp real între toți participanții cu același id de sesiune. La conectare, fiecare participant trimite un eveniment de tip “participant-joined”, eveniment ce va fi distribuit către restul instanțelor ce ascultă pe acest canal, astfel fiecare primește lista actualizată a participanților la sesiune.

Chat în timp real cu participanții din aceeași clasă virtuală

Utilizând același canal ca și mai sus, pentru chat instant, după scrierea unui mesaj in căsuța de chat, acesta va fi transmis printr-un eveniment de tip ”chat-message” care va fi distribuit celorlalți participanți.

Vizualizarea unei lecții în cadrul clasei virtuale

În interiorul clasei virtuale pot fi prezentate lecții având posibilitatea de a naviga printre paginile acesteia.

Utilizarea diferitelor unelte de desen (creion, dreptunghi, linie, marker, radieră)

Asupra materialelor afișate în interiorul sesiunii se pot face modificări cu ajutorul uneltelor de desen, utilizatorul poate astfel desena liber cu creionul, adăuga dreptunghiuri, linii și chiar poate folosi markerul pentru evidențierea unor elemente din pagină.

Adăugarea de studenți noi și asignarea acestora în clase virtuale

Profesorul, din panoul de administrare, poate crea conturi noi de studenți, poate actualiza și modifica informațiile acestora cât și să îi adauge in clase virtuale deja existente.

Adăugarea și modificarea claselor virtuale

Ca și profesor, acesta poate crea clase noi, poate modifica și șterge clase existente, poate adăuga studenți si profesori.

Adăugarea și modificarea sesiunilor aferente

In panoul de administrare, profesorul poate adăuga, șterge și programa sesiuni în clasa virtuală, poate modifica datele la care o sesiune va fi disponibilă.

Adăugarea și modificarea categoriilor de materiale

În secțiunea ”categorii” din panoul de administrare, profesorul poate adăuga, modifica și șterge categoriile în care vor fi grupate materialele disponibile atât profesorilor cât și studenților în cadrul clasei virtuale.

Adăugarea de materiale in diferite categorii

După adăugarea unei categorii, în aceasta se pot crea, modifica și șterge diferite lecții.

Adăugare de profesori noi

Ca și administrator, pe lângă toate funcționalitățile descrise mai sus, acesta poate crea, modifica și șterge conturile profesorilor, cât și crea alte conturi pentru administratori.

Specificații non-funcționale

Interfața prietenoasă

Dat fiind faptul că aplicația va fi folosită in special de persoane în folosul dezvoltării personale, platforma trebuie să fie ușor de utilizat, oferind astfel o experiență cât mai plăcută.

Utilizabilitate

Datorită interfeței prietenoase, platforma oferă o interfață grafică intuitivă, astfel încât utilizarea acesteia poate deveni o plăcere pentru utilizatorii acesteia, realizând într-un mod mai plăcut interacțiunea dintre utilizatori.

Securitatea

Securitatea este un aspect foarte important al sistemului, platforma permițând doar utilizatorilor autentificați să acceseze materialele existente, permite doar profesorilor să creeze materiale și conturi pentru studenți, conturi ce pot fi folosite doar pentru consumarea de materiale nu și ștergerea acestora și permite doar administratorilor să creeze conturi pentru profesori. Fiecare request făcut către api și socket server este însoțit de un token unic care se generează la autentificarea utilizatorului în platformă.

Performanța

Când vorbim de performanțele sistemului, vorbim despre timpul de răspuns al acestuia, executarea interogărilor și afișarea rezultatelor. Acesta trebuie să fie optim indiferent de numărul utilizatorilor care accesează concomitent platformă, indiferent de complexitatea interogărilor si a executării acestora pe o bază de date ce va crește în timp. Executarea interogărilor trebuie să fi realizate într-un timp optim pentru ca activitatea utilizatorului să nu fie întreruptă de blocarea sistemului sau de așteptarea după informații din partea acestuia.

Scalabilitatea

Prin scalabilitatea sistemului ne referim la abilitatea acestuia de a suporta un volum de încărcare sau de a permite extinderea sa. Vorbim de un sistem de stocare și prelucrare a datelor scalabil dacă se comportă similar chiar dacă volumul de date pe care îl prelucrează continuă să crească. Acesta fiind unul dintre motivele pentru folosirea unei baze de date NoSQL, fapt ce permite scalarea acesteia atât pe orizontală ( pe mai multe servere ) precum și abilitatea acesteia de a replica și distribui datele pe mai multe servere. Din dorința de scalabilitate a platformei s-a folosit și o infrastructură bazată pe containere Docker, având astfel posibilitatea de a porni mai multe instanțe din fiecare serviciu, traficul fiind balansat între ele folosind un load balancer.

Robustețe

Platforma trebuie să nu fie vulnerabilă la erori produse de introducerea de date invalide de către utilizatorii acesteia, aceasta trebuie să se comporte rezonabil, returnând un mesaj în care să informeze utilizatorul asupra datelor introduse greșit.

Studiu bibliografic

Arhitectura REST

Serviciul REST (Representantional State Transfer) reprezintă un stil arhitectural pentru sisteme hypermedia distribuite cum ar fi aplicațiile web. În cadrul acestora, nu se pune accent pe implementarea acestora cât pe rolul fiecărei componente și pe un set de interacțiunile dintre acestea.

Scopul acestei arhitecturi este de a crește performanța, scalabilitatea, simplicitatea, portabilitatea respectiv vizibilitatea sistemelor distribuite, conform [1]. Astfel, într-un context mai larg, serviciul descrie o interfață care transmite și consumă date prin HTTP, evitând utilizarea sesiunilor prin folosirea cookie-urilor HTTP.

În cadrul acestuia, transmiterea datelor nu este restrânsă doar la HTTP. Se pot astfel dezvolta aplicații software care să respecte arhitectura REST dar fără utilizarea protocolului HTTP. Printre principalele exemple de implementare putem enumera transmiterea datelor utilizând fișiere XML sau prin reprezentarea acestora in format JSON (JavaScript Object Notation).

Arhitectura REST (Representational State Transfer) a fost introdusă și definită de către Roy Fielding în teza acestuia de doctorat când studia la Universitatea Irvine California. Acesta introduce conceptul că în REST totul este o resursă, astfel orice poate fi stocat poate fi considerat o resursă. Posibile resurse ar fi:

o listă de utilizatori

statistici asupra unui produs

un nou material încărcat în platformă

Astfel, în cele mai multe cazuri, metodele folosite pentru implementarea serviciilor REST sunt așa numitele HTTP verbs:

GET – citirea unei resurse fără modificarea acesteia. Executarea repetată a acestei metode va returna același set de date, având același efect ca și o singură execuție.

POST – utilizată pentru crearea unei noi resurse. (adesea folosită și la modificarea unei resurse existente datorită unor limitări in implementarea HTTP verbs care nu permit de exemplu încărcarea de fișiere prin metoda PUT). Execuția acestei metode va avea efecte distincte.

PUT – modificarea unei resurse existente, astfel execuția repetată a acesteia va avea același efect ca și execuția singulară.

DELETE – folosită în ștergerea unei resurse existente. Execuția repetată a acesteia va avea același efect ca și execuția singulară a acesteia.

Caracteristici ale arhitecturii REST:

este o arhitectură client-server bazată pe resurse

este un stil arhitectural bazat pe standardele Web

adresa resurselor unei aplicații ce implementează servicii REST sunt adesea de forma http://{server}:{port}/{resursa}/{id} de exemplu un request la endpointul http://localhost:80/user/1 ar returna resursa de tip user cu id-ul 1

tratarea erorilor se realizează conform standardului HTTP

arhitectura REST nu este limitată în reprezentarea datelor, acestea putând fi reprezentate în diferite forme precum XML, JSON, TEXT, JPEG, OCTET- STREAM cât timp acestea respectă standardele protocolului în care sunt implementate.

Utilizând metode de caching, clienții pot crește performanța și scalabilitatea aplicației.

Arhitectura Three-Tier

Arhitectura Three-Tier, dezvoltată de către J. Donovan, reprezintă o arhitectură tip client – server în care interfața cu utilizatorul (layer-ul de prezentare), logica funcțională (layer-ul de business) și layer-ul de date sunt dezvoltate și menținute ca și module independente, adesea fiind separate pe diferite platforme.

Datorită separării între module, cu interfețe bine definite, arhitectura 3-tier intenționează să permită dezvoltatorului posibilitatea de a actualiza oricare dintre nivele fără a avea implicații asupra celorlalte. De exemplu, dacă se dorește schimbarea modalității de stocare a datelor, de la o bază de date NoSql la o bază de date relațională, singurul modul care va fi modificat va fi cel de stocare a datelor.

Arhitectura Three-Tier prezintă 3 mari module:

Nivelul de prezentare

Nivelul logic

Nivelul de stocare a datelor

Nivelul de prezentare

Reprezintă nivelul superior al aplicației, prezentând informații legate de anumite servicii cum ar fi căutarea și achiziționarea de produse, gestionarea resurselor . Acest nivel transmite informații și anumite resurse spre client respectiv comunică cu celelalte nivele din interiorul aplicației. Datorită separării și ierarhiei dintre nivele, nivelul de prezentare va comunica exclusiv cu nivelul logic.

Nivelul logic

Reprezintă legătura dintre nivelul superior al aplicației și nivelul de stocare a datelor. Fiind nivelul de mijloc, doar acesta are o conexiune directă cu nivelul de stocare, astfel pentru utilizator acesta reprezintă o abstractizare a bazei de date . La acest nivel se execută operații asupra datelor înainte de a fi transmise către stocare. Exemple de operații pot fi: validarea informațiilor primite de la client, procesarea fișierelor încărcate, eliminarea informațiilor confidențiale din resursele cerute de client.

Nivelul de stocare a datelor

Conține atât mecanismele de stocare a datelor ( servere de baze de date ) cât și cele de căutare și retragere a acestora . Nivelul de stocare trebuie să expună un API accesibil nivelului logic care să permită accesul la baza de date cât și executarea unor operații pe baza de date, dar fără să creeze dependințe în mecanismul de stocare. Astfel o modificare a arhitecturii bazei de date nu va afecta nivelul logic.

În figura următoare pot fi vizualizate cele 3 nivele, respectiv modalitatea de comunicare dintre acestea:

Arhitectura Flux (Unidirectional Data Flow)

Arhitectura Flux a fost dezvoltată de către Facebook pentru implementarea de aplicații web pe partea de client (client-side). Aceasta complementează framework-ul (React), framework bazat pe componente prin utilizarea unui flux de date unidirecțional, astfel, când un utilizator interacționează cu o componentă React, aceasta propagă printr-un dispatcher central informații către diferitele data store-uri care, după prelucrarea și stocarea acestora le trimit mai apoi copiilor lor.

Arhitectura flux are 3 mari componente:

Dispatcher-ul

Data store-uri

View-uri (de cele mai multe ori fiind reprezentate de componente React)

Fluxul de date

Informațiile într-o aplicație ce implementează arhitectura flux se propagă într-o singură direcție:

Un flux de date unidirecțional este central arhitecturii flux, iar diagrama de mai sus ar trebui să reprezinte principalul model mental asupra arhitecturii în mintea unui programator ce o implementează. Dispatcherul, store-urile și view-urile sunt noduri independente cu interfețe de intrare și ieșire bine definite. Acțiunile sunt obiecte simple ce conțin noile informații și o proprietate tip ce le identifică.

View-urile pot cauza o nouă acțiune în sistem în urma interacțiunii utilizatorilor cu acestea:

Acțiunile, care de cele mai multe ori își au originea în interacțiunea utilizatorilor cu aplicația, sunt trimise către dispatcher. Acesta mai apoi invocă callback-urile pe care store-urile le înregistrează în dispatcher la inițializare, trimițând astfel acțiunea către toate store-urile. După ce store-urile își modifică starea internă în raport cu acțiunea primită, vor emite un event de tip change care va altera controllerele view-urilor că există o modificare în layer-ul de date. Acestea mai apoi vor prelua noul set de date actualizându-și astfel starea, fapt care va forța o re-randare a view-urilor.

Starea aplicației este menținută doar în store-uri fapt care permite independența și decuplarea diferitelor componente ale aplicației. În cazurile în care apar dependințe intre store-uri, acestea sunt păstrate într-o ierarhie strictă, dispatcher-ul ocupându-se de actualizarea sincronă a acestora.

Structură

Dispatcher

Dispatcherul este punctul central care controlează fluxul de date în aplicație. În fundal acesta se comportă ca un registru de callback-uri pe care store-urile le înregistrează neavând o inteligență reală, fiind doar un mecanism simplu de a propaga action-urile în store-uri.

Pe măsură ce aplicația crește, dispatcher-ul devine din ce în ce mai vital, deoarece poate controla dependințele dintre store-uri prin invocarea callback-urilor aferente într-o anumită ordine. Astfel store-urile pot aștepta unul după altul să își termine de actualizat starea și mai apoi să se actualizeze ele însăși.

Data Store

Data store-urile conțin starea și logica aplicației. Rolul acestora este puțin similar cu cel al model-urilor în arhitectura MVC (Model-View-Controller) însă acestea păstrează starea mai multor obiecte de diferite tipuri, nu reprezintă doar un singur obiect cum o fac modelele ORM sau o colecție de obiecte de un singur tip cum o fac colecțiile din Backbone. Astfel data store-urile controlează starea unui domeniu din aplicație.

Cum am menționat mai sus, store-urile își înregistrează un callback în dispatcher. Acest callback primește acțiunea din dispatcher ca și parametru. În cadrul acestui callback există o instrucțiune de tip switch pe tipul acțiunii, aceasta fiind folosită pentru interpretarea și procesarea acesteia. Astfel o acțiune produce o actualizare a state-ului interior.

View

Sunt componente organizate într-o ierarhie care primesc starea store-ului și se actualizează pe baza acesteia. Pe nivelele de sus ale ierarhiei avem așa numitele controller-views, acestea sunt componente smart care, când primesc un event de tip update, iau noul state al store-ului, își setează propriul state și se rerandează, fapt care forțează toate componentele pe nivelele inferioare ale ierarhiei să se actualizeze.

Action

Action-urile sunt event-uri ce conțin seturi de date care vor afecta starea următoare a aplicației.

Analiză și fundamentare teoretică

Docker

Arhitectura Docker

Potrivit Docker este o platformă folosită pentru dezvoltarea, livrarea și rularea aplicațiilor. Scopul acestei platforme este de a îmbunătății portabilitatea și viteza de lansare a aplicațiilor scurtând durata procesului dintre scrierea codului și rularea acestuia în producție. În plus Docker aduce o separare a aplicației și a infrastructurii pe care rulează.

Docker funcționează pe un sistem bazat pe containere. Ca deosebire față de mașinile virtuale, containerele vor fi independente de infrastructura și sistemul de operare pe care rulează.

Figura 4.1 Arhitectura Docker

Docker folosește o arhitectură tip client-server. Clientul docker comunică în mod direct cu Docker daemon care efectiv rulează operațiile de build, rulare și livrare a containerelor. Docker client si docker daemon pot să ruleze pe același sistem sau se pot fi distribuite pe sisteme diferite utilizând o conexiune TCP. Comunicarea dintre client si server se realizează prin sockets sau prin intermediul unui API pus la dispoziție.

Docker images

Imaginile docker sunt fișiere de sistem predefinite ce vor fi utilizate de către Docker. De exemplu, o imagine docker poate conține un sistem de operare cu o bază de date relațională, sau un server web. Aceste imagini se construiesc aplicând modificări asupra unei imagini de bază.

Exemplu de imagini existente: “ubuntu:16.04”, “node:7.5-slim”, “mysql: latest”.

Conform , o imagine este formată din mai multe layere. Astfel fiecare instrucțiune RUN dintr-un fișier Dockerfile creează un nou layer peste cele existente ale imaginii. Imaginile, de cele mai multe ori tind să fie cât mai minimaliste, oferind doar ceea ce este strict necesar rulării unui singur proces. Toate layerele inferioare sunt read-only, doar layer-ul superior fiind writable.

Exemplu de fișier dockerfile:

FROM node:7.5-slim

MAINTAINER Darius Cupsa <cupsadarius@gmail.com>

RUN apt-get update

RUN apt-get upgrade

RUN npm install –g generaptr

ENTRYPOINT /bin/node

Pentru crearea unei imagini se folosește comanda ”build”. Exemplu ”docker build –d imagine-noua:tag .”. Această comandă creează o imagine nouă cu numele ”imagine-noua” cu tag-ul ”tag” bazată pe imaginea ”node:7.5-slim” și executând comenzile de update / upgrade. Dacă la rularea imaginii nu se folosește nici un parametru. Se va executa comanda de la ENTRYPOINT.

Docker containers

Docker container este o instanță a unei imagini Docker. Pentru a rula un container se utilizează comanda ”run”. Ca exemplu vom starta un container pornind de la imaginea creată anterior. Exemplu: ”docker run –d –name container-nou imagine-noua:tag”.

Un container trebuie să ruleze o singură aplicație sau un singur proces, containerul rămânând activ până la finalizarea execuției. Odată cu terminarea procesului, containerul se va opri automat.

Să presupunem că avem o aplicație scrisă în node js care este conectată la o bază de date mongo. Pentru rularea acesteia vom avea nevoie de două containere: un container de mongo care să ruleze serverul mongo al bazei de date, respectiv un container care să ruleze aplicația node. Pentru conectarea celor două containere, la rularea containerului node se va folosi comanda ”– link”. Exemplu: ”docker run –d –p 80:80 –name node –link=mongo:mongo node:7.5”.

Datorită separării față de infrastructura pe care rulează, fiecare container docker poate rula propria distribuție Linux. În cazul de mai sus prezentat imaginea de mongo poate să conțină un sistem de operare Ubuntu 16.04 pe care rulează instanța de mongo iar imaginea de nodejs poate conține un sistem de operare Ubuntu 17.10 pe care să ruleze serverul de node.

NodeJs

Conform , Node.js este o platformă construită pe motorul V8 al Chrome și se bazează pe un model event-driven și non-blocking I/O, folosind callback-uri utilizat în construcția de aplicații scalabile.

În exemplul următor mai multe conexiuni pot fi rezolvate concomitent, astfel când un request este primit calback-ul este apelat, dar dacă nu există nici un request în stack serverul va intra în sleep.

Figura 4.3 Exemplu node.js Hello World

Exemple de utilizări ale Node.js:

API-uri lightweight REST / JSON

Aplicații în timp real – aplicații web, rețele de socializare și instant messaging, software de chat, dashboard-uri pentru monitorizare în timp real

Aplicații single-page

Aplicații event-driven

Aplicații care trebuie să proceseze mii de conexiuni

Dispozitive IoT – tehnologie ”wearable”, dispozitive embeded și robotică

Avantaje ale folosirii Node.Js:

scalabil, datorită arhitecturii asincrone

rapid, atât din punct de vedere al executării cât și a timpului de dezvoltare

cod scris într-un singur limbaj, poate fi rulat pe mai multe platforme

oferă posibilitatea de a proiecta pe partea de client cât și pe cea de server într-un fel care nu necesită oscilarea între multiple tehnologii

foarte mare plaja de extensii și module open source

datorită operării pe un singur thread, abordării event-driven și a modelului non-blocking I/O, Node.Js practic acceptă în permanență requesturi.

Figura 4.4 Comparație număr requesturi procesate

Figura 4.5 Cerințe HTTP + CPU

Baze de date NoSQL

În ultimii 20 de ani, bazele de date relaționale sunt una din modalitățile de stocare preferate ale arhitecților în proiectarea aplicațiilor. Deși, în ultima perioadă bazele de date NoSQL au început să câștige din ce în ce mai mult teren. Aceste baze de date au apărut din necesitatea unor companii mari precum Amazon, Google sau Facebook de a manipula și organiza cantități uriașe de date, date cărora bazele de date relaționale nu le-ar putea face față. De aceea, bazele de date NoSQL au fost proiectate pentru stocarea unor volume uriașe de informații, în general distribuite pe mai multe servere.

Stocarea informațiilor în baze de date NoSQL poate lua mai multe forme precum: colecții cheie-valoare, implementări BigTable, colecții de documente și baze de date orientate pe grafuri.

Bazele de date NoSQL prezintă câteva caracteristici unice:

abilitatea de a scala orizontal pe mai multe servere

abilitatea de a replica și distribuii pe mai multe servere

abilitatea de a adăuga dinamic noi atribute la înregistrările existente

utilizare eficientă a indexării distribuite și a memoriei RAM pentru o stocare eficientă

O altă caracteristică importantă a sistemelor NoSQL este arhitectura ”share nothing”. În această arhitectură, fiecare nod este independent, niciunul nu partajează spațiu sau memorie. Datorită acestei arhitecturi bazele de date NoSQL pot efectua un număr foarte mare de operații de scriere și citire. O simplă operație asupra bazei de date se numește OLTP (online transaction processing).

Chiar dacă bazele de date NoSQL vin cu avantajele prezentate mai sus, au și dezavantaje. Una dintre cele mai importate fiind faptul că baza de date este formată dintr-un număr foarte mare de relații (colecții), iar modificare acestei scheme poate duce la modificarea aplicației ce depinde de aceasta. Totodată, dimensiunea colecțiilor poate crește foarte mult. Un alt dezavantaj al acestora este lipsa de maturitate, bazele de date fiind la primele versiuni sau chiar in faze incipiente.

RethinkDB

RethinkDB este prima bază de date JSON, scalabilă, open-source proiectată în special pentru aplicații web în timp real. Se diferențiază față de bazele de date NoSQL tradiționale prin modul în care datele pot fi accesate, astfel developer-ul nu trebuie să ceară constant noi seturi de date, poate doar să ceară bazei de date să trimită în continuu noi seturi de date pentru aplicații în timp real.

Baza de date RethinkDB este extrem de utilă când aplicația dezvoltată are nevoie de un flux constant de date. Tipurile convenționale de interogare funcționează bine în aplicațiile web deoarece se mapează direct pe modelul HTTP request-response. Totuși aplicațiile moderne necesită ca datele să fie trimise direct în timp real către client.

Tipuri de aplicații în care se pretează utilizarea RethinkDB:

aplicații web și mobile colaborative

aplicații pentru streaming

jocuri multiplayer

marketplace în timp real

Principalele tipuri de date suportate pentru câmpurile unui document sunt:

tipuri scalare: integer, double, float, boolean

tipuri șir de caractere: string, expresii regulate, cod

obiecte similare cu JSON

Datorită acestei flexibilități, developerul poate să modifice rapid structura obiectelor salvate în baza de date. Acest lucru este foarte util într-o aplicație în care apar constant modificarea cerințelor existente.

Exemplu de document salvat într-o bază de date RethinkDB:

{

“nume”: “Cupsa”,

“prenume”: “Darius”,

“email”: [

“cupsadarius@gmail.com”,

],

“adresa”: {

“strada”: “Bucegi”,

“numar”: “2A”,

“localitate”: “Cluj-Napoca”,

“cod”: 400667,

}

}

TypeScript

TypeScript este un superset peste ECMAScript 2015 (ES2015). Fiecare program scris in JavaScript este și un program TypeScript valid. Compilatorul pentru TypeScript face doar operații asupra fișierelor locale acestea fiind convertite în JavaScript și mai apoi rulate.

Sintaxa utilizată de TypeScript include toate funcționalitățile din ECMAScript 2015 incluzând clasele și modulele, iar pe lângă acestea oferă posibilitatea de a transpila aceste funcționalități în cod valid pentru ECMAScript 3 și 5.

Utilizând TypeScript oferă developerilor posibilitatea de a scrie cod într-un mod orientat pe obiecte, făcând posibilă utilizarea paradigmelor ce devin posibile o dată cu aceasta.

Conform , pe lângă toate avantajele prezentate mai sus, TypeScript oferă și posibilitatea de a scrie cod într-un mod strongly-typed punând la dispoziția programatorilor un set de adnotări asemănătoare cu comentariile JSDoc găsite in sistemele Clojure însă în TypeScript acestea sunt integrate direct în sintaxă, făcând codul mult mai ușor de citit și înțeles, reducând astfel necesitatea de mentenanță.

Figura 4.6 Exemplu TypeScript

Express.js

Express.js sau simplu Express este un framework pentru aplicații web ce rulează pe Node.js publicat ca și software open source sub licența MIT. A fost proiectat pentru dezvoltarea de aplicații web și API-uri, devenind în scurt timp de la lansare cel mai răspândit framework în ecosistemul Node.js.

Autorul original, TJ Holowaychuk, descrie Express ca și un server minimal cu multe facilități și un ecosistem bogat de module și pluginuri.

Express face parte din suita MEAN împreună cu MongoDB ca și bază de date, Express ca și backend server și AngularJs ca și framework pe frontend.

Socket.io

Socket.io este o librărie JavaScript pentru aplicații în timp real. Aceasta pune la dispoziție un canal de comunicare bidirecțional între clienți web și server. Librăria pune la dispoziție două părți, una pentru client ce rulează în browser și una pentru server ce rulează pe NodeJs. Amândouă pun la dispoziție un API foarte similar și funcționează ca și Node.js pe un sistem bazat pe eventuri.

Socket.io folosește în principiu WebSockets ca și protocol de comunicare. Deși de multe ori este folosită doar ca și un wrapper peste WebSockets, socket.io permite cu mult mai mult, cum ar fi posibilitatea de a emite către mai multe socketuri o data, stocare de date asociate cu fiecare client, operații I/O asincrone, etc.

ReactJs

React este o librărie JavaScript open source utilizată în crearea de interfețe pentru utilizatori. Este menținută de Facebook, Instagram și o mare comunitate de dezvoltatori. După ultimele statistici librăria este folosită de către site-uri precum: Netflix, Imgur, Feedly, Airbnb și alții.

Facilități

Flux de date unidirecțional

Seturi de date sunt trimise către componente pe baza cărora acestea randează content HTML. Totuși o componentă nu poate să modifice direct proprietățile primite, emite un action care va avea ca și consecință modificarea state-ului.

Virtual DOM

React creează un cache în memorie pe care execută toate operațiile, calculează diferențele și apoi actualizează DOM-ul browserului . Fapt ce permite programatorului să scrie cod ca și cum întreaga pagină ar fi randată o dată, React ocupându-se de actualizarea fiecărei componente când există o schimbare.

JSX

Componentele React sunt de cele mai multe ori scrise în JSX, acesta fiind o extensie a sintaxei JavaScript ce permite utilizarea de cod HTML ca și string-uri.

Proiectare și implementare

Detalii de proiectare

Cazuri de utilizare

În această secțiune vor fi prezentate principalele funcționalități ale aplicației sub forma unor cazuri de utilizare.

Considerăm un caz de utilizare, o colecție de scenarii de succes și eșec care descriu setul de acțiuni realizate de sistem pentru obținerea unui rezultat de către actor. Actorul este o entitate cu un comportament specific, spre exemplu o persoană, un alt sistem, etc. În sistemul proiectat se pot identifica trei actori principali:

Student: orice utilizator al aplicației are și rolul de student. După logarea în sistem, acesta poate realiza o multitudine de activități precum vizualizarea claselor virtuale din care face parte, vizualizarea și accesarea sesiunilor precedente cât și vizualizarea sesiunilor viitoare.

Profesor: adiacent acțiunilor posibile studenților, profesorii pot face cu mult mai mult, cum ar fi adăugarea și modificarea conturilor studenților, a claselor virtuale, a categoriilor de materiale și a materialelor cât și crearea de sesiuni virtuale și modificarea acestora.

Administrator: pe lângă acțiunile moștenite de la tipurile de actori prezentați antecedent, administratorul are abilitatea de a crea, modifica și șterge conturi de tip profesor.

Diagramă cazuri de utilizare student

Cazul principal de utilizare constă în accesarea clasei virtuale de către actor, în contextul unei sesiuni.

Posibile cazuri de utilizare pentru un utilizator tip student:

Login în aplicație

Vizualizarea claselor virtuale din care face parte

Vizualizarea sesiunilor precedente

Vizualizarea sesiunilor viitoare

Accesarea unei sesiuni în clasa virtuală

Figura 5.1 Diagramă cazuri utilizare pentru un student

În continuare vom prezenta unul dintre aceste cazuri de utilizare:

Nume caz de utilizare: Accesarea unei sesiuni în clasa virtuală

Actorul principal: Utilizatorul tip student

Scurtă descriere: De fiecare dată când un student dorește să acceseze o sesiune în cadrul clasei virtuale, aplicația va prelua id-ul sesiunii, va cere informațiile necesare accesării materialului de la api, va autentifica utilizatorul într-un socket room-ul asignat sesiunii fapt ce va permite comunicarea în timp real între participanții aceleiași sesiuni.

Succesiunea evenimentelor:

START caz de utilizare

Studentul accesează linkul aferent sesiunii pe care dorește să o deschidă

Se efectuează un HTTP request către API cu id-ul sesiunii

După primirea răspunsului ce conține informații despre participanții la sesiune cât și materialul aferent acesteia, aplicația va autentifica utilizatorul către serverul socket

După autentificarea cu succes, un event tip ParticipantJoin va fi emis către ceilalți participanți în sesiune

FINALIZARE caz de utilizare

Momentul în care utilizatorul student este anunțat despre succesul sau eșecul acțiunii sale, cazul de utilizare ia sfârșit.

Cerințe speciale:

Sistemul nu trebuie să permită accesul persoanelor neautentificate, asigurând astfel integritatea și securitatea datelor utilizatorilor deja existenți.

Precondiții:

Linkul aferent sesiunii trebuie să conțină id-ul sesiunii cât și id-ul materialului ce urmează a fi afișat, iar acesta trebuie să fie accesat de către un utilizator tip student.

Postcondiții:

API-ul returnează un răspuns ce conține informații cu privire la participanții aferenți sesiunii cât și date referitoare la lecția ce va fi susținută.

Serverul de socket trebuie să accepte conexiunea utilizatorului cât și să distribuie eventurile primite de la acesta.

Dacă a existat un schimb de informații, acestea sunt stocate și trebuie să rămână persistente.

Prioritate: Este obligatoriu ca sistemul să execute acești pași când linkul către sesiune este accesat.

Disponibilitate: disponibil tot timpul.

Frecvența de utilizare: este variabilă, aceasta depinde de numărul de utilizatori activi în aplicație cât și de numărul de sesiuni programate în momentul accesării.

Diagramă cazuri de utilizare profesor

Cazul principal de utilizare constă în efectuarea următoarelor activități de către actor, în cazul de față actorul estre un utilizator tip profesor. Un profesor este orice utilizator care are rolul de profesor în sistem.

Posibile cazuri de utilizare ale unui utilizator tip profesor, pe lângă cele moștenite de la utilizatorii tip studenți:

Adăugare conturi studenți

Modificare conturi studenți

Ștergere conturi studenți

Adăugare clase virtuale

Modificare clase virtuale

Ștergere clase virtuale

Adăugare sesiuni

Modificare sesiuni

Ștergere sesiuni

Adăugare categorii materiale

Modificare categorii materiale

Ștergere categorii materiale

Adăugare lecții

Modificare lecții

Ștergere lecții

Figura 5.2 Diagramă cazuri utilizare profesor

În continuare vom prezenta în detaliu unul dintre aceste cazuri de utilizare.

Nume caz de utilizare: Adăugare lecție

Actorul principal: Utilizatorul profesor

Scurtă descriere: După autentificare, un profesor are opțiunea de a adăuga un nou material didactic, pe lângă alte opțiuni disponibile.

Succesiunea evenimentelor:

START caz de utilizare

Utilizatorul accesează aplicația și se autentifică în aceasta

După logare, acesta va fi redirecționat către pagina de administrare a platformei unde acesta are opțiunea de a adăuga un nou material didactic

Utilizatorul inserează titlul lecției

Utilizatorul inserează descrierea acesteia

Utilizatorul alege din dropdown categoria din care materialul face parte

Utilizatorul adaugă fiecare pagină din material ca imagine ce urmează a fi încărcată

Utilizatorul apasă butonul ”SAVE”

Lecția apare în tabelul adiacent formularului de inserare

FINALIZARE caz de utilizare

Cazul de utilizare a luat sfârșit atunci când noua lecție adăugată apare în tabelul cu lecții existente în sistem.

Excepții:

Utilizatorul nu se poate autentifica în aplicație deoarece acesta nu are un cont valid

Această problemă poate fi remediată doar de către un administrator al sistemului.

Utilizatorul apasă butonul ”SAVE” fără a completa unul din câmpurile titlu, categorie, pagina

Aplicația va afișa un mesaj de eroare prin care avertizează starea invalidă a formularului de adăugare

Se va continua de la pasul 3

Cerințe speciale:

Sistemul nu trebuie să permită accesul persoanelor neautentificate, asigurând astfel integritatea și securitatea datelor utilizatorilor deja existenți.

Precondiții:

Utilizatorul trebuie să fie autentificat în sistem

Utilizatorul trebuie să fie de tip profesor

Postcondiții:

Datele sunt trimise către API unde vor fi stocate

Noua lecție apare în tabelul cu materialele existente

Prioritate: rămâne la latitudinea utilizatorul dacă dorește sau nu să folosească această funcționalitate.

Frecvența de utilizare: relativă, rămâne la latitudinea utilizatorului.

Diagramă cazuri de utilizare administrator

Cazul principal de utilizare a acestui tip de actor constă în adăugarea de noi conturi de tip profesor. Un administrator este un utilizator ce a fost creat la prima inițializare a aplicației.

Adăugare conturi profesori

Modificare conturi profesori

Ștergere conturi profesori

Figura 5.3 Diagramă cazuri de utilizare administrator

În continuare se va prezenta în detaliu unul dintre aceste cazuri de utilizare.

Nume caz de utilizare: Adăugare cont profesor

Actor principal: Utilizator administrator

Scurtă descriere: După autentificare, utilizatorul va fi redirecționat către pagina de administrare a platformei unde acesta are posibilitatea de a adăuga noi conturi de tip profesor, pe lângă celelalte opțiuni disponibile moștenite de la tipurile inferioare de utilizatori (profesor, student).

Succesiunea evenimentelor:

START caz de utilizare

Utilizatorul accesează aplicația și se autentifică în aceasta

După logare, acesta va fi redirecționat către pagina de administrare a platformei unde acesta are opțiunea de a adăuga un nou cont de tip profesor

Utilizatorul inserează numele profesorului

Utilizatorul inserează prenumele profesorului

Utilizatorul inserează adresa de email a profesorului

Utilizatorul inserează numărul de telefon al profesorului

Utilizatorul inserează o parolă pentru contul profesorului

Utilizatorul apasă butonul ”SAVE”

Noul cont al profesorului apare în tabelul adiacent formularului de adăugare

FINALIZARE caz de utilizare

Cazul de utilizare ia sfârșit când contul profesorului apare în lista cu conturi existente în sistem.

Excepții:

Utilizatorul nu se poate autentifica în aplicație deoarece acesta nu are un cont valid

Această problemă poate fi remediată doar de către un administrator al sistemului.

Utilizatorul apasă butonul ”SAVE” fără a completa unul din câmpurile nume, prenume, email, telefon, parolă

Aplicația va afișa un mesaj de eroare prin care avertizează starea invalidă a formularului de adăugare

Se va continua de la pasul 3

Cerințe speciale:

Sistemul nu trebuie să permită accesul persoanelor neautentificate, asigurând astfel integritatea și securitatea datelor utilizatorilor deja existenți.

Precondiții:

Utilizatorul trebuie să fie autentificat în sistem

Utilizatorul trebuie să fie de tip administrator

Postcondiții:

Datele sunt trimise către API unde vor fi stocate

Nou cont apare în tabelul cu profesori existenți

Prioritate: rămâne la latitudinea utilizatorul dacă dorește sau nu să folosească această funcționalitate.

Frecvența de utilizare: relativă, rămâne la latitudinea utilizatorului.

Diagrame de secvență

Diagrama de secvență descrie interacțiunea dintre două sau mai multe entități și ordinea mesajelor ce sunt transmise între acestea. Totodată arată modul în care instanțele comunică într-un anumit caz de utilizare.

În continuare vor fi prezentate diagramele de secvență pentru trei dintre cele mai importante funcționalități ale aplicației:

Autentificarea în cadrul aplicației

Adăugarea unei lecții noi

Accesarea unei sesiuni în cadrul clasei virtuale

Diagrama de secvență pentru autentificarea în aplicație

Diagrama de secvență este ilustrată în Figura 5.4 Diagrama de secvență a autentificării în aplicație.

Figura 5.4 Diagrama de secvență a autentificării în aplicație

Componenta Login afișează un dialog prin care oferă utilizatorului posibilitatea de autentificare prin introducerea unei adrese de email și o parolă validă. După inserarea acestora, componenta trimite un event de tip LoginEvent în Dispatcher, event ce apoi este propagat de către acesta în Auth Api de unde un request HTTP va fi transmis către API.

Când request-ul ajunge la API, acesta va fi tratat de către Auth Controller în handler-ul rutei ”/authentificate”. Aici un obiect ce conține emailul utilizatorului si parola acestuia va fi construit din body-ul requestului primit, obiect ce mai apoi va fi transmis serviciului de autentificare care, folosind emailul va apela metoda getByEmail din User Service, metodă ce va transmite cererea mai departe către User Repository.

Dacă nu există un utilizator în baza de date cu același email o excepție va fi aruncată, excepție ce va fi mapată pe un obiect de tip response si transmisă aplicației de frontend unde un mesaj corespunzător va fi afișat. Totuși dacă există un utilizator în baza de date, informațiile referitoare la acesta vor fi returnate user service-ului și mai apoi auth service-ului unde validarea parolei va avea parte.

Dacă parola nu este validă o excepție va fi aruncată și tratată ca în cazul precedent, dar dacă parola este validă un JWToken va fi generat pe baza informațiilor primite, acesta fiind mai apoi returnat aplicației de frontend care, la primirea acestuia el va fi stocat și utilizat pentru toate request-urile viitoare.

În urma primirii token-ului, un nou request va fi făcut către API, request ce va fi trată tot în Auth Controller în handler-ul rutei ”/current-user”. Aici token-ul primit va fi decodificat și validat de către metoda validate din auth service. Dacă token-ul este valid, informațiile din acesta vor fi returnate către frontend fiind salvate pentru utilizări viitoare.

Dacă autentificarea a fost executată cu succes putem afirma că aplicația de frontend are la dispoziție un JWToken valid și un obiect ce conține informațiile utilizatorului logat, cât și faptul că utilizatorul a fost redirecționat către pagina de administrare unde poate vizualiza informațiile referitoare la clasele virtuale din care aparține cât și sesiunile precedente și viitoare din care poate face parte.

Diagramă de secvență pentru adăugarea unui material didactic nou

Diagrama secvențială este ilustrată în Figura 5.5 Diagrama de secvență pentru adăugarea unui nou material didactic.

Componenta lesson form pune la dispoziția utilizatorului un formular pentru adăugarea de materiale didactice noi. Acesta conține câmpuri pentru titlu, descriere, categoria din care face parte, cât și oricâte câmpuri de upload pentru paginile materialului. După completarea acestora și trimiterea formularului, componenta apelează un callback primit din Lesson Page numit saveLesson trimițând ca parametru noul obiect format din datele luate din formular, care mai apoi este transformat într-un event de tip NewLessonEvent ce cu ajutorul Dispatcherului global ajunge în Lesson Api.

Handler-ul eventului NewLessonEvent din Lesson API va face un request HTTP cu informațiile primite de la dispatcher către API. Când request-ul este primit de către API, acesta este procesat de către câteva middleware care pe lângă autorizare va procesa fiecare fișier încărcat ca și pagină în material apoi va permite requestului să ajungă în controller.

Când request-ul a ajuns în Lesson Controller putem asuma că fișierele încărcate există deja pe server astfel putem trece la procesarea requestului. În controller un obiect ce conține toate informațiile de pe request va fi creat și transmis serviciului lesson service împreună cu array-ul ce conține informațiile referitoare la fișierele încărcate. După maparea acestora pe o instanță a clasei Lesson, obiectul va fi validat utilizând un set de validatori. Dacă după validare există erori acestea vor fi mapate pe un obiect de tip response și transmise către frontend unde un mesaj de eroare corespunzător va fi afișat, iar dacă obiectul este valid acesta va fi salvat în baza de date cu ajutorul unei instanțe a clasei Lesson Repository, clasă ce facilitează operațiile asupra bazei de date. Dacă salvarea în baza de date s-a efectuat cu succes, un id va fi returnat aplicației de frontend.

La primirea id-ului noului material didactic creat, un nou request va fi făcut către API pentru preluarea unei noi liste cu materialele disponibile. După primirea acesteia, un nou event ce conține noua lecție va fi trimis dispatcherului, care îl va propaga în Lesson Store unde acesta își va actualiza starea internă. Bazat pe noua stare a store-ului, componentele Lesson Page și Lesson Form se vor actualiza reprezentând modificările față de starea precedentă.

Diagrama de secvență pentru accesarea unei sesiuni în cadrul clasei virtuale

Diagrama secvențială este ilustrată în Figura 5.6 Diagrama secvențială pentru accesarea unei sesiuni în cadrul clasei virtuale.

Figura 5.6 Diagrama secvențială pentru accesarea unei sesiuni în cadrul clasei virtuale

Când o sesiune este deschisă în cadrul clasei virtuale aceasta trimite ca parametrii constructorului acesteia id-ul sesiunii și pe cel al materialului didactic ce va fi susținut. Având acces la aceste informații, clasa virtuală va emite un event în dispatcher de tip GetLessonEvent, event ce va fi propagat către Lesson API unde un request HTTP va fi făcut către API, acesta fiind tratat ca în cazurile exemplificate anterior.

Astfel, când clasa virtuală primește instanța materialului de la API, va continua la conectarea către serverul de socket. Va emite un event de tip SocketConnect ce va conține id-ul sesiunii, id-ul utilizatorului și token-ul primit la autentificare. Pe baza acestor informații socket serverul va autentifica utilizatorul folosind aceeași secvență descrisă la 5.1.2.1. După autentificarea utilizatorului, un room specific sesiunii va fi creat, room la care toți viitorii participanți vor fi adăugați, menținând astfel integritatea datelor.

După conectarea cu succes la serverul socket se emite un event de tip ParticipantJoined, când acest event ajunge în room-ul sesiunii, pe lângă faptul că acest mesaj va fi distribuit celorlalți participanți, utilizatorul care a transmis eventul va primi toate eventurile persistate în trecut în cadrul sesiunii sortate după un revision id, aducând astfel utilizatorul la starea curentă a sesiunii în desfășurare.

Detalii de implementare

Sistemul proiectat în lucrarea de față este compus din trei componente majore, fiecare având un rol bine definit: partea de server sau backend-ul aplicației, partea de socket server sau serverul pentru comunicarea în timp real și partea de client sau frontend-ul aplicației.

Toate aceste module sunt dezvoltate pe o infrastructură bazată pe containere Docker, fiecare modul fiind un container expunând doar un reverse proxy, fapt ce permite scalarea aplicației în funcție de necesitate cât și balansarea sarcinii pe componente.

Partea de API este reprezentată de o aplicație Node.js și frameworkul Express.js dezvoltată utilizând mediul de dezvoltare WebStorm 2016.1.

Partea de comunicare în timp real sau socket serverul este tot o aplicație Node.js și frameworkul Socket.io dezvoltată în același IDE.

Clientul este reprezentat de către o aplicație web disponibilă în toate browserele moderne scrisă pe baza framework-ului React și implementând printre altele arhitectura flux.

După cum se poate observa în diagrama de deployment, comunicarea dintre module se realizează folosind protocolul HTTP și arhitectura REST pentru comunicarea dintre client si API, respectiv protocolul RFC 6455 pentru comunicarea dintre client si serverul de socket. Conținutul cererilor și răspunsurilor vor fi transmise în format JSON fiind astfel ușor de parsat de către client.

Prin alegerea arhitecturii REST și a celei client-server se realizează cu adevărat o separare uniformă a componentelor și a atribuțiilor fiecăreia. Astfel, stocarea și procesarea datelor este principala atribuție a serverului, menținerea informațiilor referitoare la comunicarea în timp real cât și procesarea si stocarea evenimentelor transmise printre acestea este principala funcționalitate a socket serverului, iar interfațarea acestora cu utilizatorul intră în atribuția clientului. Astfel componentele pot fi dezvoltate independent și ar putea fi înlocuită cu ușurință, atât timp cât interfața dintre componente și modul de comunicare rămâne același, fapt care determină astfel simplitatea și scalabilitatea sistemului.

În Figura 5.7 Diagrama de deployment a sistemuluieste prezentată diagrama de deployment a întregului sistem, evidențiind astfel principalele componente prezentate anterior.

Figura 5.7 Diagrama de deployment a sistemului

În continuare, se vor prezenta în detaliu fiecare componentă din diagrama de deployment, evidențiind modul de comunicare dintre componente în interiorul sistemului.

Arhitectura bazei de date

Pentru stocarea și organizarea datelor transmise în interiorul sistemului se folosește RethinkDb, o implementare a bazelor de date NoSQL. Este o bază de date ușor de manipulat și înțeles având posibilitatea de a lucra cu volume mari de date, astfel fiind utilizată atât în proiecte mari cât și în proiecte mici.

În figura următoare este prezentată arhitectura bazei de date, evidențiind legăturile dintre colecții.

După cum se poate observa în figura precedentă, avem 7 colecții: Users, Blacklist, Events, Categories, Lessons, Sessions și Classrooms.

Colecția Users

În această colecție sunt stocate principalele date de identificare a unui utilizator, printre care se regăsesc: informații personale precum nume, prenume, email, număr de telefon.

Principalele câmpuri ale colecției sunt:

id – id-ul utilizatorului

firstName – prenumele utilizatorului

lastName – numele utilizatorului

email – adresa de email a utilizatorului

phoneNumber – numărul de telefon

salt – hash generat utilizat în criptarea parolei

password – parola criptată utilizând algoritmul bcrypt

roles – array de roluri pe care le deține utilizatorul, roluri ce regulează accesul la anumite funcționalități din aplicație

Unele informații sunt completate direct de către client: firstName, lastName, email, phoneNumber iar restul sunt completate de către server. De exemplu, salt, pasword și roles sunt completate de către sistem la crearea utilizatorului în sistem.

Colecția Blacklist

În această colecție sunt stocate doar JSONWebtokens precedente pe care utilizatorul a ales să le invalideze chiar dacă acestea nu au expirat încă. Este utilizată în procesul de autorizare, iar un nou token este adăugat doar când un utilizator alege să se delogheze din aplicație.

Principalele câmpuri ale colecției sunt:

id

token

Colecția Categories

Colecția categories conține informațiile ce descriu categoriile de materiale din sistem. Acestea pot fi create de către administrator și profesori.

Principalele câmpuri ale colecției sunt:

id

name – numele categoriei

description – o scurtă descriere asupra categoriei

Colecția Lessons

În această colecție sunt păstrate informații cu referire la materialele didactice disponibile în sistem cât și informații despre slide-urile ce aparțin acestora.

Principalele câmpuri ale colecției sunt:

id

categoryId – id-ul categoriei din care face parte

title – titlul materialului didactic

description – o scurtă descriere a acestuia

slides – un array de elemente de tip slide ce descriu fiecare pagină a materialului

Principalele câmpuri ale unui slide sunt:

id

name – numele fisierului

order – ordinea în material

path – calea către fișier

type – mimeType-ul fisierului

Colecția Sessions

În această colecție sunt persistate informațiile despre sesiunile precedente cât și cele viitoare ce au luat parte în cadrul sistemului.

Principalele câmpuri ale colecției sunt:

id

lessonId – id-ul materialului susținut în sesiune

startDate – data de început a sesiunii

endDate – momentul în care sesiunea intră in review

Colecția Classrooms

În cadrul acestei colecții sunt stocate informații referitoare la clasele virtuale adăugate în sistem. Printre alte informații acestea conțin un set de sesiuni precedente cât și viitoare, un array de studenți și unul de profesori,

Principalele câmpuri ale colecției sunt:

id

name – numele clasei virtuale

lastSessionId – id-ul ultimei sesiuni deschise în cadrul clasei virtuale

sessions – un array de sesiuni

students – o listă cu studenții ce aparțin clasei virtuale

teachers – o listă cu profesorii ce susțin materiale în cadrul clasei

Colecția Events

În colecția events vor fi păstrate toate eventurile trimise prin intermediul serverului de comunicare în timp real care au un nivel de persistență indefinită. Aceste eventuri păstrează pe lângă informații necesare identificării sesiunii și a utilizatorului ce le-a emis date referitoare la acțiunile efectuate de către participanți în cadrul unei sesiuni cum ar fi un nou desen adăugat sau un nou mesaj transmis în chat.

Principalele câmpuri ale colecției sunt:

id

sesssionId – id-ul sesiunii în cadrul căreia eventul a fost transmis

slideId – id-ul slide-ului asupra căreia acțiunea descrisă în event trebuie aplicată

userId – id-ul user-ului ce a emis eventul

type – tipul eventului

revision – conține numărul de ordine al eventului în contextul întregii sesiuni, câmp ce va fi utilizat în ordonarea cronologică a eventurilor

persistenceLevel – nivelul de persistență al eventurilor

data – obiect ce va conține orice informație necesară pentru descrierea unei acțiuni în cadrul clasei virtuale.

Aplicația server principală

API-ul aplicației folosește se bazează pe paradigma programării orientată pe obiecte utilizând NodeJs precum utilizarea suprasetului TypeScript cât și a framework-ului ExpressJs.

Soluția acestui modul al sistemului este alcătuită din trei mari pachete, fiecare din ele reprezentând o parte din arhitectura three-tier.

În figura următoare este prezentat modul de comunicare dintre cele trei pachete.

În continuare vom prezenta fiecare pachet mai în detaliu.

Pachetul database layer

Acest pachet reprezintă fundația arhitecturii three-tier. Conține mecanisme de stocare și acces asupra datelor. La rândul lui pachetul conține câteva subpachete: models, repositories, mappers, validators.

Pachetul models conține modelele necesare în cadrul aplicației. Fiecare clasă în acest pachet extinde clasa BaseModel, clasă ce implementează câteva metode utile.

Pachetul repositories conține clasele necesare conectării la baza de date precum și interfața de comunicare cu implementările de rigoare necesare interacționării cu aceasta.

Pachetul mappers conține logica necesară conversiei datelor înspre și dinspre baza de date, logică ce permite utilizarea entităților în cadrul aplicației și maparea automată către acestea.

Pachetul validators conține logica de validare a datelor stocate într-o entitate, validare ce se execută de fiecare dată când o modificare a datelor din baza de date este efectuată.

Figura 5.10 diagrama de clase apartenente modulului modelsprezintă succint diagrama de clase din cadrul submodulului models.

Figura 5.11 diagrama de clase a pachetului repositoriesreprezintă diagrama de clase apartenente modulului repositories.

În cadrul acestui pachet se poate observa metodele de bază în interfațarea cu baza de date clasă ce va fi extinsă de către fiecare repository specific entității. Repository-urile acestea mai apoi vor implementa metode specifice entităților ce le deservesc.

După cum am specificat în capitolele anterioare, ca suport pentru baza de date s-a ales o bază de date NoSql și anume RethinkDb. Pentru implementarea interogărilor s-a folosit driverul acestora pentru NodeJs cu o interfață custom dezvoltată în cadrul acestei aplicații.

Figura 5.12 diagrama claselor în pachetul mappersreprezintă diagrama claselor în pachetul mappers.

Figura 5.12 diagrama claselor în pachetul mappers

Pachetul mappers pune la dispoziția programatorului logica necesară mapării documentelor din baza de date asupra modelelor definite în cadrul aplicației, mapare ce se face automat în interiorul repository-ului specific entității.

Modulul pune la dispoziție un factory public, care pe baza clasei entității returnează o instanță a mapper-ului necesar entității. Fiecare mapper implementează o interfață generică ce forțează clasa să expună două metode bine definite.

Astfel la apelarea funcției hydrate cu o instanță a entității ce urmează a fi mapată și un obiect cu datele necesare, mapper-ul va popula instanța cu datele pertinente din obiect. La fel, când funcție dehydrate este apelată cu o instanță a entității, mapper-ul va returna un simplu obiect JSON cu informațiile stocate în entitate.

Figura 5.14 diagrama claselor din pachetul validatorsprezintă în detaliu diagrama claselor în pachetul validators cât și dependințele dintre acestea.

Figura 5.14 diagrama claselor din pachetul validators

Astfel modulul validators pune la dispoziție o serie de validatori simplii care mai apoi vor fi utilizați în validarea informațiilor înainte de salvarea acestora.

Pachetul pune la dispoziția programatorului un factory public prin care, pe baza entității se poate accesa o instanță a validatorului specific entității.

Pachetul service layer

Acest pachet reprezintă layer-ul de mijloc în cadrul arhitecturii three-tier. Conține logica de business a aplicației precum și interacțiunile dintre modele cât și procesarea datelor primite de la utilizator.

Modulul conține câteva clase principale și anume:

authService – serviciul responsabil de autentificarea și autorizarea utilizatorului

userService – serviciu ce implementează logica necesară entității de tip User

attendeeService – acest serviciu extinde logica din userService și adaugă unele metode specifice diferitelor tipuri de utilizatori din cadrul sistemului

categoryService – serviciu responsabil de procesarea informațiilor referitoare la categoriile de materiale

lessonService – conține partea de business ce permite manipularea entităților de tip lesson

sessionServie – serviciu ce agregă metodele necesare lucrului cu entități de tip session

classroomService – implementează logica de business utilizată în procesarea informațiilor referitoare la entități de tip classroom.

În figura următoare se pot observa interacțiunile dintre clasele ce fac parte din acest pachet.

Pachetul presentation layer

Acest pachet reprezintă nivelul superior din arhitectura three-tier. În cadrul acestui pachet se definesc resursele cu care utilizatorul va avea posibilitatea de a interacționa. Conține diferite subpachete: controllers, utils și middleware.

În figurile următoare vor fi prezentate clasele ce fac parte din pachetele menționate anterior.

În pachetul middlewares sunt implementate câteva funcții ajutătoare layer-ului de prezentare. Aceste funcții sunt metode ce au acces atât la informațiile din request cât și la obiectul ce urmează a fi transmis ca și response.

Aceste funcții middleware pot executa următoarele operațiuni:

pot executa orice cod

pot modifica informațiile din request sau response

pot încheia ciclul request-ului returnând prematur un response

pot apela următorul middleware din stack

Dacă middleware-ul curent nu încheie ciclul request-ului acesta este obligat să apeleze la sfârșitul executării următorul middleware din stack.

În cazul aplicației noastre sunt implementate patru astfel de middleware și anume: cors, authentificated, authorizedWithRole și uploader.

Middleware-ul prezentat mai sus realizează mecanismul CORS (Cross-origin resource sharing). Acest mecanism permite aplicațiilor aparținătoare altor domenii să acceseze serviciile REST implementate în acest modul. Acest lucru fiind realizat prin adăugarea unor headere în răspunsul trimis clientului.

Middleware-ul authenticated realizează validarea fiecărui request făcut către API. Acesta preia JWToken-ul de pe request și cu ajutorul serviciului de autentificare îl validează, îl decodifică, iar informația este adăugată request-ului acesta fiind mai apoi trimis ca parametru următoarelor metode ce așteaptă în stack. În caz contrar, fie când tokenul nu există sau e invalid, ciclul request-ului este întrerupt returnându-se un răspuns de eroare cu mesajul ”Invalid token”.

Funcția lambda prezentată în figura anterioară prezintă implementarea middleware-ului authorizedWithRole, middleware ce realizează verificarea accesului utilizatorului la resursele din sistem. Astfel după autentificare, dacă aceasta sa realizat cu succes, această metodă primește rolul necesar accesări resursei ca parametru și verifică dacă acesta apare în rolurile utilizatorului. Dacă autorizarea s-a efectuat și utilizatorul autentificat are rolul necesar accesării resursei, ciclul request-ului va continua în mod natural, iar în caz contrar un răspuns de eroare cu mesajul ”Unauthorized access” va fi returnat, request-ul încheindu-se aici.

Middleware-ul prezentat anterior utilizează o bine cunoscută librărie pentru upload pe NodeJs și anume multer , iar în funcția precedentă este afișată configurarea acesteia. Sunt configurate astfel modul de numire a fișierelor cât și destinația acestora. De altfel aici sunt setate și limitele acestora: maxim 100 de fișiere încărcate pe un request și o dimensiune maximă de 10MB.

Aplicația de comunicație în timp real (server-ul socket)

Aplicația de comunicare în timp real este implementată utilizând engine-ul v8 pe baza căruia funcționează NodeJs și framework-urile Express.Js și Socket.Io, librării ce facilitează realizarea acesteia.

La fel ca și aplicația precedentă aceasta implementează tot arhitectura three-tier având astfel un database layer, un business logic layer și un presentation layer.

Pachetul database layer

Acest pachet reprezintă layer-ul cel mai de jos din arhitectura three-tier. Conține mecanismele de acces și stocare a informațiilor în baza de date. La rândul lui pachetul conține câteva subpachete: models, repositories și mappers.

Figura următoare prezintă succint diagrama de clase din pachetele amintite mai sus.

Figura 5.23 diagrama claselor din pachetul mappers

Pachetul de business logic

Logica de business în contextul acestei aplicații este cuprinsă în trei clase fiecare cu funcționalitate specifică. În continuare se vor prezenta câteva funcționalități ale server-ului socket.

Similar middleware-ului de autentificare prezentat în cadrul aplicației server principală, un proces de autentificare este necesar și aici, acesta funcționând astfel: după ce un socket se conectează la server acesta va emite către server un eveniment de tip authentication ce conține JWToken-ul primit la logare. Cu ajutorul serviciului de autentificare token-ul este validat, astfel dacă acesta este corect se va continua la crearea sesiunii în cadrul server-ului, iar în caz contrar clientul va fi deconectat păstrând astfel integritatea informațiilor transmise între utilizatorii autentificați.

În figura prezentată anterior este implementat managerul de sesiuni active în sistem. Managerul utilizează design patern-ul singleton , iar instanța acestuia este creată la startarea server-ului și expune doar două metode publice, createSession și addParticipant, metode ce vor fi utilizate astfel: după autentificare utilizatorului pe baza id-ului sesiunii se va crea o sesiune în cadrul sistemului dacă aceasta nu există, după crearea sesiunii, pe baza id-ului acesteia cât și cel al participantului socket-ul aferent acestuia este adăugat în sesiune, socket ce va fi folosit pentru primirea și emiterea de evenimente pe parcursul sesiunii. De menționat aici este faptul că atunci când toți participanții părăsesc sesiunea managerul va șterge instanța acesteia eliberând astfel memoria alocată.

Dată fiind arhitectura și natura aplicației, aceasta fiind orientată pe evenimente, pentru fiecare sesiune existentă se păstrează doar starea inițială și fiecare eveniment care este emis în cadrul acesteia. Astfel după ce un utilizator este autentificat și adăugat în sesiune este apelată funcția descrisă în figura anterioară, funcție ce ia din baza de date toate evenimentele precedente momentului apelării le combină cu evenimentele ce au un nivel de persistență efemeră le sortează după id-ul reviziei și le emite utilizatorului autentificat, rezultând astfel în aducerea stării sesiunii utilizatorului la starea finală aplicând toate evenimentele emise vreodată în ordinea emiteri acestora.

Pachetul presentation layer

Dat fiind faptul că utilizatorul nu are interacțiune directă cu această aplicație, comunicarea cu aceasta și utilizarea ei este strict implementată în aplicația de front-end, pachetul acesta conține doar un endpoint folosit pentru handshake la deschiderea sesiunii.

Aplicația de frontend

Interfața sistemului cu care utilizatorul interacționează este la rândul ei o aplicație web de sine stătătoare ce implementează arhitectura flux pe baza framework-ului ReactJs utilizând JSX pentru view-uri și LESS pentru design.

Datorită arhitecturii implementate, aplicația se împarte în mai multe pachete cu funcționalități specifice și anume: actions, api, components, dispatcher, events, helpers, models, pages și stores, pachete ce vor fi prezentate mai în detaliu în rândurile următoare.

Pachetul api

Pachetul api conține logica necesară comunicării cu aplicațiile prezentate anterior. Acesta implementează metodele necesare consumării resurselor primite de la API cât și transmiterea datelor către acesta, astfel fiecare clasă din acest pachet primește event-uri de la dispatcher pe baza cărora trimite sau cere informații de la API, răspunsul acestor request-uri fiind mai apoi emis ca și alte eventuri către dispatcher.

Pachetul actions

În pachetul actions sunt implementează toate callback-urile prin care orice event va fi emis către dispatcher, astfel implementând fluxul de date unidirecțional care afirmă ca într-o aplicație flux doar prin cadrul unui action un event poate fi emis în dispatcher.

În continuare este prezentată diagrama claselor apartenente pachetului actions.

Pachetul dispatcher

Pachetul dispatcher conține o singură clasă ce implementează dispatcher-ul unic utilizat în contextul aplicației, fiind punctul central al arhitecturii, prin care sunt emise toate event-urile în aplicație, event-uri ce descriu orice acțiune efectuată.

Pachetul helpers

În pachetul helpers sunt agregate câteva clase care permite programatorului o mai ușoară implementare a unor funcționalități în sistem.

Acesta conține următoarele clase:

Base64 – librărie utilă în codificarea și decodificarea mesajelor în baza 64

DateFormatter – librărie utilizată în formatarea timestamp-urilor

LocalStorage – clasă ce implementează câteva metode utile în lucrul cu spațiul de stocare local

MD5 – librărie utilizată în codificarea stringurilor în format md5

Pachetul components

În pachetul components sunt implementate toate fragmentele ce pot fi afișate în aplicație formând astfel layer-ul de view-uri ale acesteia.

Prezentat anterior este arborele de dependințe dintre componentele vizuale ale aplicației, astfel pentru afișarea oricărei element toate componentele adiacente acestuia pe nivelele superioare ale arborelui trebuie să fie deja randate.

Spre exemplu: ca să afișăm componenta whiteboard trebuie să încărcăm componenta page care la rândul ei afișează componentele navigation, sidebar și content. În cadrul componentei content, pe baza rutei accesate, se va randa elementul classroom care va afișa în spațiul sidebar-ului o listă cu participanți și un chat, iar în container-ul principal se va încărca componenta whiteboard.

Pachetul events

Pachetul events conține toate clasele ce descriu fiecare eveniment din aplicație. Acestea se pot grupa în două categorii: specifice procesului de autentificare, specifice unei entități și evenimente specifice acțiunilor din clasa virtuală.

Evenimente specifice procesului de autentificare

LoginEvent

LoginSuccessfulEvent

LoginUnsuccessfulEvent

LogoutEvent

GetCurrentUserEvent

GetCurrentUserSuccessfullyEvent

GetCurrentUserUnsuccessfullyEvent

Evenimente specifice unei entități

LoadEvent

LoadedSuccessfullyEvent

SelectEvent

SaveEvent

DeleteEvent

FormErrorsEvent

Evenimente specifice clasei virtuale

ParticipantJoin

ChatMessage

SlideChange

PencilDrawing

EraserDrawing

LineDrawing

RectangleDrawing

HighlighterDrawing

Pachetul models

Pachetul models conține o agregare a pachetelor cu același nume din aplicațiile de server și comunicare în timp real, dat fiind faptul ca aplicația frontend comunică cu ambele, păstrându-se astfel structura datelor constantă între frontend și backend.

Pachetul pages

În cadrul acestuia sunt stocate componentele ce descriu nivelul superior al arborelui de dependințe prezentat anterior. Elementele apartenente acestui pachet sunt randate pe baza rutei accesate în sistem, astfel în nici un moment al execuției aplicației două astfel de componente nu pot coexista.

Pachetul stores

Modulul stores conține ultima parte majoră din arhitectura flux și anume data stores. Conform 3.3 store-urile sunt clase care păstrează starea aplicației si care înregistrează callback-uri în dispatcher prin care primește eventuri ce vor altera starea acestuia în iterația următoare.

Rularea sistemului

Pentru rularea aplicației sunt necesare pornirea containerelor docker în ordinea corectă a dependințelor: proxy, monitoring, baza de date, api, socket și frontend. Pentru facilitarea acestui proces sa folosit docker compose , tehnologie ce orchestrează aplicații ce necesită mai multe containere pentru rulare.

Astfel pentru facilitarea rulării sistemul câteva scripturi au fost implementate cum ar fi build.sh, install.sh, start.sh și scale.sh, scripturi ce rulează comenzi asupra infrastructurii docker.

Dacă startarea aplicațiilor server s-a realizat cu succes, terminalele sistemelor ar trebui să arate precum în figurile următoare:

După rularea scripturilor prezentate anterior, sistemul pune la dispoziție câteva intefețe pentru fiecare din sisteme:

classroom.dkr – interfața aplicației implementate

classroom.dkr:8080 – interfața proxy-ului și a load balancer-ului

monitoring.classroom.dkr – interfața serviciului de monitorizare

db.classroom.dkr – panoul de administrare al bazei de date

În figura următoare este prezentată interfața proxy-ului precum și instanțele container-ului api acesta fiind load-balanced de către proxy.

Conform 5.1.1 în sistem sunt implementate funcționalitățile necesare management-ului de clase virtuale, studenți, profesori și materiale didactice. În continuare vor fi prezentate grafic câteva dintre aceste funcționalități.

Figura precedentă reprezintă pagina principală a aplicației. Pentru accesarea acesteia utilizatorul trebuie să fie autentificat, pagina afișând informații senzitive utilizatorului sub forma tabelelor afișate ce conțin date referitoare claselor virtuale în care aparține cât și sesiunile precedente și viitoare împreună cu materialele didactice aferente acestora.

În Figura 5.42 se poate vizualiza pagina de administrare a materialelor didactice în sistem. Această pagină necesită cel puțin rolul de profesor pentru accesare datorită acțiunilor posibile în această situație.

Prezentat în Figura 5.43 vizualizarea materialului didactic și a chat-ului în clasa virtuală este o sesiune deschisă în clasa virtuală cât și funcționalitățile acesteia cum ar fi lista participanților, chatul în timp real, uneltele de desen cât și o demonstrație a acestora în figura următoare.

Testare și validare

Testarea aplicațiilor server

Testarea conexiunii cu baza de date s-a realizat atât în timpul implementării serviciilor cât și la executarea finală a testelor și rularea aplicației. Metoda principală de testare a serverului api și socket s-a realizat utilizând plugin-ul Postman.

Testarea serviciului de load-balancing și monitorizare

Pentru testarea scalabilității sistemului s-a folosit Apache Benchmarking . Cu ajutorul acestui tool se pot executa automat mii de requesturi către un endpoint testând astfel reziliența acestuia cât și timpul de răspuns al acestuia.

Un astfel de test se execută utilizând comanda: ab –n [număr total de requesturi] –c [număr requesturi concomitente] [endpoint]

Testarea aplicației ca întreg

Testarea acesteia sa realizat atât în timpul dezvoltării cât și la final. Fiecare funcționalitate a acesteia fiind executată repetat cu fiecare tip de utilizator. La rândul ei, aplicația în sine a fost testată pe mai multe sisteme de operare cum ar fi Windows, Ubuntu și Mac Os X confirmând astfel abilitatea platformei de a rula în orice tip de environment.

Concluzii

Concluzii

Obiectivul principal al acestui sistem este de a facilita accesul la materiale didactice, cât și la sesiuni de predare cu profesori acreditați într-un mediu virtual. În acest scop s-a încercat utilizarea tehnologiilor emergente. Proiectarea sistemului de față a inclus în componența sa o aplicație web accesibilă din orice browser modern.

Funcționalitățile sistemului au fost implementate în totalitate, aplicația îndeplinind cu succes următoarele activități:

Logarea în aplicatie folosind adresa de email și parola

Vizualizarea claselor în care aparții și a sesiunile aferente acestora

Accesarea clasei virtuale

Listă cu participanții care au accesat aceeași clasă virtuală

Chat în timp real cu participanții în sesiunea curentă

Vizualizarea unui material didactic în clasa virtuală

Utilizarea diferitelor unelte de desen

Adăugarea de noi studenți și gruparea acestora în clase

Adăugarea și modificarea claselor virtuale

Adăugarea și modificarea sesiunilor aferente acestora

Adăugarea de categorii de materiale

Adăugarea de materiale didactice și gruparea acestora în categorii

Adăugarea de noi profesori

Sistemul este format din trei componente majore: două componente de server și o aplicație web. Aceste aplicații au fost implementate individual, ulterior fiind testată integritatea acestora în contextul întregului sistem. Testarea acestora s-a realizat atât manual prin parcurgerea diferitelor flow-uri în aplicație cât și prin rularea de teste automate utilizând Postman si Apache benchmark.

Așadar, proiectul este un sistem distribuit ce facilitează accesul la materiale didactice, singura condiție fiind deținerea unui calculator cu acces la internet și un browser relativ modern.

Dezvoltări ulterioare

Pentru o viitoare versiune a sistemului se pot aduce îmbunătățiri atât în privința aplicațiilor de server cât și în componenta de web.

În cazul aplicației server principale se pot aduce următoarele îmbunătățiri:

Implementarea unui serviciu de notificări prin email când o sesiune urmează să devină disponibilă

Rafinarea sistemului de autorizare, permițând o granulare mai atentă a accesului la informațiile din sistem

Încărcarea slide-urilor în Cloud facilitând astfel scalabilitatea sistemului

În cazul serverului de comunicare în timp real se pot aduce îmbunătățiri la managementul sesiunilor mutând această funcționalitate din memorie într-un sistem de sine stătător.

De asemenea, o nouă versiune a aplicației web ar putea aduce câteva funcționalități noi în forma:

Implementării unei unelte de adăugare de text

Implementării unui sistem de comunicare audio / video utilizând WebRTC

Îmbunătățirii rezilienței funcționalităților existente

Datorită contextului căruia sistemul este destinat, îmbunătățirea aplicației este o necesitare continuă, printre actualizările obligatorii fiind creșterea performanței sistemului, reziliența acestuia la erori și rezolvarea acestora îmbunătățind astfel utilizabilitatea acestuia.

Acronime

JSON – JavaScript Object Notation

API – Application Programming Interface

HTTP – HyperText Transfer Protocol

URI – Union Resource Identifier

REST – Representational State Transfer

NoSQL – Not Only SQL

JWT – Json Web Token

Similar Posts