Tehnologia Informat ,iei [617911]

Universitatea Politehnica Timis ,oara
Facultatea de Automatic ˘a s,i Calculatoare
Departamentul Calculatoare s ,i
Tehnologia Informat ,iei
PLANNING -APLICAT ,IE INTELIGENT ˘A
PENTRU PLANIFICAREA RESURSELOR
DINTR -O COMPANIE
Proiect de diplom˘ a
Ioana Carmen ALBIS ,ORU
Coordonator s ,tiint ,ific:
S,. l. Dr. Ing. R ˘azvan Dorel CIOARG ˘A
Timis ,oara
Iunie, 2019

Cuprins
List˘ a de figuri iii
List˘ a de secvent ,e de cod vi
1 Introducere 1
1.1 Dezvoltarea aplicat ,iilor web . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Contextul de realizare al aplicat ,iei Planning . . . . . . . . . . . . . . . . . 2
1.3 Specificat ,ii generale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Structura lucr ˘arii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4.1 Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4.2 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4.3 Prezentare teoretic ˘a – stadiul actual al subdomeniului . . . . . . . 4
1.4.4 Prezentare general ˘a a proiectului . . . . . . . . . . . . . . . . . . . 4
1.4.5 Detalii de proiectare, implementare s ,i operare . . . . . . . . . . . 4
1.4.6 Rezultate s ,i concluzii . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4.7 Epilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Fundamentare teoretic˘ a 5
2.1 Arhitectura bazat ˘a pe microservicii . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Arhitectura bazat ˘a pe nivele . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 JHipster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Oracle JET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.5 jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.6 Require.JS s ,i Knockout.JS . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.7 JS Promises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.8 Spring Boot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.9 REST API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.10 Liquibase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.11 Hibernate s ,i JPA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.12 Stream API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.13 Alte tehnologii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
i

CUPRINS
3 Descriere general˘ a a aplicat ,iei 13
3.1 Aplicat ,ia Planning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4 Detalii de proiectare s ,i implementare 17
4.1 Arhitectura microserviciului Planning . . . . . . . . . . . . . . . . . . . . 17
4.2 Componentele microserviciului Planning . . . . . . . . . . . . . . . . . . 18
4.2.1 Nivelul de prezentare a datelor . . . . . . . . . . . . . . . . . . . . 18
4.2.2 Nivelul de business logic . . . . . . . . . . . . . . . . . . . . . . . 20
4.2.3 Nivelul de accesare a datelor . . . . . . . . . . . . . . . . . . . . . 21
4.3 Baza de date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.4 Aplicat ,ia client Planning . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.4.1 Generarea gridului cu date . . . . . . . . . . . . . . . . . . . . . . 28
4.4.2 Obt ,inerea efortului depus de un angajat . . . . . . . . . . . . . . . 29
4.4.3 Rutarea paginilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.5 Comunicarea inter-server . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.6 Implementarea serviciilor REST . . . . . . . . . . . . . . . . . . . . . . . . 35
4.6.1 Generarea planific ˘arilor pentru angajat ,i . . . . . . . . . . . . . . . 36
4.6.2 Deducerea num ˘arului de zile ˆın care un angajat e disponibil . . . 38
4.6.3 Generarea num ˘arului de zile neplanificate pentru un angajat ,ii
dintr-un departament . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.7 Autentificarea s ,i autorizarea . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5 Operarea, testarea s ,i performant ,ele aplicat ,iei 47
5.1 Mecanismul de deployment . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2 Testarea aplicat ,iei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.3 Rezultate experimentale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.3.1 Analiza performant ,ei la runtime . . . . . . . . . . . . . . . . . . . 50
5.3.2 Analiza performant ,ei pe baza opiniei utilizatorilor . . . . . . . . 52
6 Concluzii s ,i perspective 55
6.1 Concluzii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.2 Sinteza contribut ,iilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.3 Direct ,ii de continuare a dezvolt ˘arii . . . . . . . . . . . . . . . . . . . . . . 57
Referint ,e bibliografice 59
ANEXA 1: Ghidul utilizatorului 66
ii

List˘ a de figuri
2.1 Cubul scal ˘arii [1] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Arhitectura Oracle JET [4] . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1 Arhitectura bazat ˘a pe microservicii a aplicat ,iei Planning (inspirat din: [2]) 13
4.1 Arhitectura microserviciului Planning . . . . . . . . . . . . . . . . . . . . 17
4.2 Componentele microserviciului Planning [7] . . . . . . . . . . . . . . . . 18
4.3 Interact ,iunea dintre componentele arhitecturii . . . . . . . . . . . . . . . 19
4.4 Diagrama bazei de date planning ˆın JDL . . . . . . . . . . . . . . . . . . . 24
4.5 Diagrama bazei de date employee ˆın JDL . . . . . . . . . . . . . . . . . . 25
4.6 Descrierea arhitecturii MVVM [4] . . . . . . . . . . . . . . . . . . . . . . . 27
4.7 Interact ,iunea dintre componentele paginii Planning . . . . . . . . . . . . 30
4.8 Parametrii din URL pentru pagina Planning . . . . . . . . . . . . . . . . 33
4.9 Parametrii din URL pentru pagina Overview . . . . . . . . . . . . . . . . 33
4.10 Exemplu de header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.11 Diagrama de secvent ,˘a pentru calculul disponibilit ˘at,ii unui angajat . . . 39
4.12 Etapele mecanismului de autentificare s ,i autorizare [9] . . . . . . . . . . 42
5.1 Diagrama de deployment [10] . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2 Fis ,ierele necesare test ˘arii Karma . . . . . . . . . . . . . . . . . . . . . . . 49
5.3 Metricile de performant ,˘a laˆınc˘arcarea paginii Overview . . . . . . . . . 51
5.4 Analiza utiliz ˘arii CPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.5 Analiza cauzei utiliz ˘arii maxime a CPU-ului pe anumite port ,iuni . . . . 52
5.6 R ˘aspunsuri la ˆıntrebarea 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.7 R ˘aspunsuri la ˆıntrebarea 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.8 R ˘aspunsuri la ˆıntrebarea 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.9 R ˘aspunsuri la ˆıntrebarea 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
.0.1 Pagina de autentificare din Keycloak . . . . . . . . . . . . . . . . . . . . . 61
.0.2 Canvasul paginii Planning . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
.0.3 Grila cu date din pagina Planning ˆın modul de editare al duratei . . . . . 62
.0.4 Grila cu date din pagina Planning ˆın modul de editare al eficient ,ei . . . . 63
.0.5 Popup cu mesaj de eroare pentru valoare gres ,it˘a a duratei . . . . . . . . 64
iii

LIST ˘A DE FIGURI
.0.6 Popup cu mesaj de eroare pentru valoare gres ,it˘a a eficient ,ei . . . . . . . 64
.0.7 Grila cu date din pagina Overview . . . . . . . . . . . . . . . . . . . . . . 65
.0.8 Canvasul paginii Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 66
.0.9 URL-ul paginii Planning . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
iv

List˘ a de secvent ,e de cod
4.1 Exemplu anotare controler . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.2 Implementare a serviciului pentru BupResourcePlanning . . . . . . . . . 20
4.3 Implementarea map ˘arii pentru BupCustomer . . . . . . . . . . . . . . . . 21
4.4 Implementarea BupResourcePlanningRepository . . . . . . . . . . . . . . 21
4.5 Exemplu query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.6 Implementarea entit ˘at,ii BupResourcePlanning . . . . . . . . . . . . . . . 22
4.7 Configurare H2 database pentru profilul dev . . . . . . . . . . . . . . . . 23
4.8 Configurare Oracle database pentru profilul prod . . . . . . . . . . . . . 23
4.9 Componenta oj-data-grid din Planning . . . . . . . . . . . . . . . . . . . 28
4.10 Metodele clasei UIPlanning . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.11 Afis ,area gridului cu date ˆın pagina Planning . . . . . . . . . . . . . . . . 29
4.12 Metoda cu ajutorul c ˘areia se fac cererile GET la server . . . . . . . . . . . 31
4.13 Funct ,ia care preia efortul s ,iˆıl returneaz ˘aˆıntr-un Promise . . . . . . . . . 31
4.14 Funct ,ia din view care apeleaz ˘a serviciul . . . . . . . . . . . . . . . . . . . 32
4.15 Scrierea valorii efortului ˆın grid . . . . . . . . . . . . . . . . . . . . . . . . 32
4.16 Dependent ,a Maven pentru OpenFeign . . . . . . . . . . . . . . . . . . . . 34
4.17 Configurarea clientului Feign . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.18 Interfat ,a clientului Feign . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.19 Realizarea autoriz ˘arii folosind interceptorul . . . . . . . . . . . . . . . . . 35
4.20 Generarea planific ˘arilor pentru un angajat . . . . . . . . . . . . . . . . . . 37
4.21 Preluarea datelor despre angajat ,i prin clientul Feign . . . . . . . . . . . . 40
4.22 Entitatea BupAggregatedPlanning . . . . . . . . . . . . . . . . . . . . . . 40
4.23 Generarea planific ˘arilor agregate . . . . . . . . . . . . . . . . . . . . . . . 41
4.24 Dependent ,a Maven pentru Spring Starter for AAD . . . . . . . . . . . . 42
4.25 Filtrul de autentificare pentru microserviciul Planning . . . . . . . . . . . 43
4.26 Configurare Microsoft Azure Active Directory . . . . . . . . . . . . . . . 44
4.27 Configurarea securit ˘at,ii pentru microserviciul Planning . . . . . . . . . . 44
4.28 Rolurile utilizatorilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.29 Configurare OAuth2 pentru profilul dev . . . . . . . . . . . . . . . . . . . 45
5.1 Anotarea claselor de test . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.2 Init ,ializarea datelor pentru testele Karma . . . . . . . . . . . . . . . . . . 49
v

LIST ˘A DE SECVENT ,E DE COD
5.3 Testarea gener ˘arii trimestrelor ˆıntr-un interval de timp dat . . . . . . . . 50
vi

1 Introducere
Fiecare companie are un set propriu de procese, produse s ,i servicii, pe care le rea-
lizeaz ˘aˆın mod distinctiv fat ,˘a de alte companii. Astfel, implementarea ˆıntr-o companie
a unui sistem Enterprise Resource Planning (ERP), adic ˘a a unui sistem de aplicat ,ii in-
tegrate care se ocup ˘a automat de anumite operat ,iuni pe care angajat ,ii le efectueaz ˘a,
este extrem de util ˘aˆın optimizarea operat ,iunilor s ,i sporirea eficient ,ei angajat ,ilor. Fiind
vorba de un sistem software complex ˆın care orice schimbare afecteaz ˘aˆıntregul sistem,
acesta trebuie s ˘a fie scalabil, rapid s ,i us ,or de utilizat.
1.1 Dezvoltarea aplicat ,iilor web
O aplicat ,ie web este o aplicat ,ie client-software rulat ˘aˆın browser, care afis ,eaz˘a
informat ,iile primite de la server. Aplicat ,iile web sunt importante pentru dezvolta-
rea internetului, iar odat ˘a cu cres ,terea masei de utilizatori, s ,i as ,tept˘arile din partea
software-ului au crescut. Cu c ˆat aplicat ,iile web sunt mai rapide, cu atat cres ,te s ,i calita-
tea utiliz ˘arii browserului.
Aplicat ,iile web au evoluat din site-urile web, care erau de fapt depozite cu docu-
mente statice ce afis ,au aceeas ,i informat ,ie pentru tot ,i utilizatorii, la aplicat ,ii distribuite
complexe, cu pagini web dinamice, securitate, autentificare a utilizatorilor s ,i arhitec-
tur˘a complex ˘a.
Calitatea aplicat ,iilor Web este influent ,at˘a de arhitectura pe care se bazeaz ˘a. O
aplicat ,ie dezvoltat ˘a sub form ˘a de monolit combin ˘a toate componentele sale ˆıntr-un
singur fis ,ier WAR s ,i des ,i laˆınceput este us ,or de dezvoltat, testat s ,i rulat, ˆın timp codul
ajunge at ˆat de complex ˆıncˆat este greu de dezvoltat s ,i ment ,inut, iar shimb ˘arile mi-
nore pot duce la rezultate neas ,teptate. Pe lang ˘a acestea, o aplicat ,ie monolit e greu de
scalat s ,i reutilizat. Astfel, ca solut ,ie la problemele enumerate, s-a c ˘autat o modalitate
de a organiza o aplicat ,ie web sub form ˘a de suit ˘a de servicii modulare (componente
slab cuplate), s ,i s-a dezvoltat arhitectura bazat ˘a pe microservicii, ˆın care componentele
aplicat ,iei au dimensiuni relativ mici, comunic ˘aˆıntre ele, pot fi reutilizate, sunt us ,or de
ment ,inut s ,i testat s ,i arhitectura e usor de scalat.
1

CAPITOLUL 1. INTRODUCERE
1.2 Contextul de realizare al aplicat ,iei Planning
Aplicat ,ia Planning a fost dezvoltat ˘aˆın cadrul companiei SC Virtual7 Rom ˆania
SRL. Virtual7 este o companie cu aproximativ 70 de angajat ,i, cu sedii ˆın Germania,
Elvet ,ia s ,i Rom ˆania, care ofer ˘a consultant ,˘a s,i dezvolt ˘a aplicat ,ii web personalizate pen-
tru client ,i din domeniul public.
Planificarea disponibilit ˘at,ii angajat ,ilorˆın cadrul companiei Virtual7 era realizat ˘a
de s ,efii departamentelor de dezvoltare software folosind o aplicat ,ie monolit foarte
lent˘a s,i cu interfat ,˘a neprietenoas ˘a, fapt care avea efecte negative atat asupra eficient ,ei
planificatorului, c ˆat s ,i asupra corectitudinii datelor introduse ˆın sistem. Aplicat ,ia a
fost dezvoltat ˘aˆın Oracle Applicat ,ion Development Framework (ADF), un framework
mai vechi cu ajutorul c ˘aruia se dezvolt ˘a aplicat ,ii enterprise cu flexibilitate put ,in˘a s ,i
cod complex. Din cauza motivelor enumerate anterior, ˆın cadrul companiei era foarte
important s ˘a existe o aplicat ,ie web accesibil ˘a de oriunde, care s ˘a fie folosit ˘a pentru
a planifica disponibilitatea angajat ,ilorˆın funct ,ie de mai mult ,i factori (tip de contract,
vacant ,e, zile libere legale, etc.), rapid, f ˘ar˘a efort s ,i f˘ar˘a erori. De asemenea, aplicat ,ia
trebuia s ˘a fie modular ˘a, astfel ˆıncˆat s˘a poat ˘a fi integrat ˘a cu us ,urint ,˘a cu alte aplicat ,ii
interne ale companiei.
Astfel, lucrarea de fat ,˘aˆıs,i propune realizarea unei aplicat ,ii web single page , cu ar-
hitectur ˘a bazat ˘a pe microservicii, cu ajutorul c ˘areia se vor planifica resursele din com-
panie. Resursele sunt reprezentate de angajat ,ii companiei, iar planificarea se va realiza
ˆın funct ,ie de disponibilitatea angajatului. Pentru determinarea disponibilit ˘at,ii fiec ˘arui
angajat, se vor lua ˆın calcul zilele sale de concediu, zilele libere legale, timpul petrecut
ˆın c˘al˘atoriile efectuate ˆın interes de serviciu, tipul de contract s ,i eficient ,a angajatu-
lui. Prin comparat ,ie cu aplicat ,ia de planificare veche, noua aplicat ,ie trebuie s ˘a aib ˘a
performant ,˘a s,i utilizabilitate mai bune.
1.3 Specificat ,ii generale
ˆIn cadrul aplicat ,iei Planning, microserviciul de planificare (Planning) trebuie s ˘a
gestioneze toate operat ,iunile necesare pentru a face planificarea pe termen scurt s ,i pe
termen lung a unit ˘at,ilor operat ,ionale. Informat ,iile legate de angajat ,i (legatura dintre
angajat ,i s,i departamente, vacant ,e s,i c˘al˘atorii planificate), sunt gestionate de microser-
viciul Employee. Planificarea trebuie s ˘a iaˆın considerare urm ˘atoarele:
Tipul de contract pentru angajat ,i
–%timp (%time) – definit pentru fiecare angajat, este procentul corespunz ˘ator
num ˘arului de ore pe care acesta le lucreaz ˘aˆın fiecare zi (de exemplu, 50%
ˆınseamn ˘a c˘a angajatul lucreaz ˘a 4 ore pe zi s ,i 20 de ore pe s ˘apt˘amˆan˘a);
2

CAPITOLUL 1. INTRODUCERE
–%timp ˆımp˘art ,it (%split time) – definit pentru angajat ,ii care nu lucreaz ˘a zilnic
de luni p ˆan˘a vineri, ci doar ˆın anumite zile (de exemplu, 50% miercuri s ,i
vineri ˆınseamn ˘a c˘a angajatul lucreaz ˘a cˆate 4 ore ˆın fiecare miercuri s ,i vineri,
deci 8 ore pe s ˘apt˘amˆan˘a).
Un angajat poate schimba tipul contractului, adic ˘a poate trece de la contract cu
norm ˘aˆıntreag ˘a la contract cu norm ˘a part ,ial˘a s,i invers;
Un angajat poate schimba departamentul, iar acest fapt poate duce la schimb ˘ari
ale zilelor libere legale dup ˘a o anumita data;
Un angajat poate avea mai multe sau mai putine zile de concediu ˆıntr-un an;
Un angajat poate decide s ˘a planifice sau s ˘a solicite o vacant ,˘aˆıntr-o lun ˘a, iar ˆın
funct ,ie de num ˘arul de zile de concediu solicitate trebuie s ˘a se reduc ˘a disponibi-
litatea resursei ˆın luna respectiv ˘a;
De asemenea, pe baza zilelor libere legale specifice unei anumite regiuni, se poate
calcula num ˘arul de zile ˆın care un angajat poate lucra ˆıntr-o lun ˘a;
Timpul petrecut ˆın c˘al˘atorie reduce de obicei disponibilitatea angajat ,ilor (de exem-
plu, dac ˘a un angajat c ˘al˘atores ,teˆın fiecare s ˘apt˘amˆan˘a, nu ˆıi vom putea planifica
disponibilitatea complet ˘a). O modalitate de planificare a disponibilit ˘at,ii angajat ,i-
lor pe proiecte care necesit ˘a ca˘al˘atorii, se foloses ,te de o variabil ˘a numit ˘a %Eficien-
t,˘a (%Efficiency) (de exemplu, pentru o resurs ˘a care are 8 ore de c ˘al˘atorie pe
s˘apt˘amˆa-n˘a, eficient ,a este de 80%).
Aplicat ,ia r˘aspunde cerint ,elor a trei categorii de utilizatori:
Utilizatorii de pe departamentul V ˆanz˘ari (Sales) pot vizualiza planific ˘arile anga-
jat,ilor;
S,efii departamentelor de dezvoltare software, ˆın colaborare cu membrii departa-
mentului de v ˆanz˘ari, planific ˘a disponibilitatea dezvoltatorilor de software;
Utilizatorii de pe departamentul Resurse Umane (Human Resources), pot vizu-
aliza planific ˘arile angajat ,ilor (de exemplu, ˆın cazul ˆın care un angajat a lucrat
prea multe ore peste program, membrul responsabil de pe departamentul Re-
surse Umane poate verifica dac ˘a i-au fost planificate prea multe ore s ,i dac ˘a orele
ˆın plus sunt justificate).
1.4 Structura lucr˘ arii
Lucrarea de fat ,˘a este ˆımp˘art ,it˘aˆın 7 p ˘art ,i, dup ˘a cum urmeaz ˘a:
3

CAPITOLUL 1. INTRODUCERE
1.4.1 Prolog
Cuprinde listele cu figurile s ,i secvent ,ele de cod ilustrate ˆın aceast ˘a lucrare s ,i cu-
prinsul ei.
1.4.2 Introducere
Acesta este primul capitol al lucr ˘arii s ,i cuprinde informat ,ii generale legate de
lucrarea s ,i proiectul de diplom ˘a. Aici sunt prezentate detalii despre domeniul abor-
dat, motivat ,ia realiz ˘arii proiectului, contextul ˆın care a fost realizat, specificat ,iile sale
generale s ,i structura lucr ˘arii.
1.4.3 Prezentare teoretic˘ a – stadiul actual al subdomeniului
Aceast ˘a sect ,iune a lucr ˘arii cuprinde Capitolul 2 ,ˆın care se prezint ˘a cˆateva not ,iuni
teoretice abordate ˆın cadrul proiectului s ,i descrierea celor mai importante tehnologii
folosite la realizarea lui.
1.4.4 Prezentare general˘ a a proiectului
Aceast ˘a parte a lucr ˘arii cuprinde Capitolul 3 ,ˆın care se ofer ˘a o privire de ansam-
blu asupra arhitecturii aplicat ,iei Planning, a funct ,ionalit ˘at,ilor implementate s ,i asupra
elementelor din care e format ˘a aplicat ,ia, la nivel de interfat ,˘a cu utilizatorul.
1.4.5 Detalii de proiectare, implementare s,i operare
Sect ,iunea cuprinde Capitolul 4 s,iCapitolul 5 , in care se detaliaz ˘a felul ˆın care a fost
gandit ˘a, implementat ˘a s ,i testat ˘a aplicat ,ia folosind tehnologiile descrise, felul ˆın care
comunic ˘a diversele componente ale sistemului, cum poate fi lansat ˘aˆın execut ,ie, dar s ,i
o analiz ˘a a performant ,ei aplicat ,iei.
1.4.6 Rezultate s,i concluzii
ˆIn ultimul capitol se discut ˘a rezultatele obt ,inute ˆın urma test ˘arii s ,i concluziile
generale la care s-a ajuns dup ˘a realizarea s ,i utilizarea aplicat ,iei. De asemenea, tot ˆın
acest capitol sunt prezentate contribut ,iileˆın realizarea proiectului s ,i posibile direct ,ii de
continuare a dezvolt ˘arii lui.
1.4.7 Epilog
Aceast ˘a sect ,iune cuprinde referint ,ele bibliografice s ,i anexele lucr ˘arii.
4

2 Fundamentare teoretic˘ a
2.1 Arhitectura bazat˘ a pe microservicii
Modularitatea este esent ,ial˘a atunci c ˆand se dezvolt ˘a aplicat ,ii mari s ,i complexe,
deoarece o aplicat ,ie modern ˘a poate deveni prea mare pentru a fi dezvoltat ˘a de un
individ s ,i prea complex ˘a pentru a fi ˆınt ,eleas ˘a de o singur ˘a persoan ˘a. Aplicat ,iile trebuie
s˘a fie descompuse ˆın module, care s ˘a fie dezvoltate s ,iˆınt ,elese de mai mult ,i oameni.
Arhitectura bazat ˘a pe microservicii este un stil arhitectural care descompune func-
t,ional o aplicat ,ieˆıntr-un set de servicii. Aceasta foloses ,teserviciul ca unitate de mo-
dularizare. Un serviciu poate fi ˆınt ,eles ca o aplicat ,ie mai mic ˘a, care implementeaz ˘a
funct ,ionalit ˘at,i axate pe un anumit domeniu (de exemplu, gestionarea comenzilor unui
magazin). Acesta are un API (Application Program Interface), iar transmiterea de date
ˆıntre servicii sau client s ,i servicii, se realizeaz ˘a doar prin intermediul API-urilor. Un
alt beneficiu al serviciilor este acela c ˘a pot fi implementate, rulate s ,i scalate indepen-
dent. De asemenea fiecare serviciu are o baz ˘a de date proprie, astfel se respect ˘a ideea
de modularitate, ˆıntruc ˆat serviciile comunic ˘a prin intermediul API-urilor s ,i sunt slab
cuplate.
Dup ˘a cum se explic ˘aˆın [1], trecerea de la o aplicat ,ie monolitic ˘a la una bazat ˘a pe
servicii se face folosind cubul scal ˘arii (vezi figura 2.1), care descrie 3 modalit ˘at,i de a
scala o aplicat ,ie:
axa X (duplicare orizontal ˘a): se execut ˘a mai multe instant ,e ale aplicat ,iei mo-
nolit sub un load balancer ; acesta distribuie cererile ˆıntre instant ,ele identice ale
aplicat ,iei; serviciile se scaleaz ˘a folosind aceast ˘a metod ˘a;
axa Y (decompozit ,ie funct ,ional ˘a): se scaleaz ˘a prin separarea lucrurilor care sunt
diferite; metoda e folosit ˘a la descompunerea aplicat ,ieiˆın servicii;
axa Z (partit ,ionarea datelor): se scaleaz ˘a prin separarea lucrurilor care sunt simi-
lare; se execut ˘a tot mai multe instant ,e ale aplicat ,iei,ˆıns˘a spre deosebire de prima
metod ˘a, fiecare instant ,˘a e responsabil ˘a de un singur subset de date [2].
Printre avantajele arhitecturii bazate pe microservicii, se num ˘ar˘a urm ˘atoarele:
permite livrarea continu ˘a s ,i implementarea unor aplicat ,ii mari s ,i complexe, servici-
ile sunt mici, us ,or de ment ,inut, pot fi implementate s ,i scalate independent, arhitectura
5

CAPITOLUL 2. FUNDAMENTARE TEORETIC ˘A
adoptarea de noi tehnologii ( ˆıntruc ˆat serviciile pot fi implementate folosind tehnologii
diferite) s ,i erorile pot fi g ˘asite mai us ,or.
Figura 2.1: Cubul scal ˘arii [1]
2.2 Arhitectura bazat˘ a pe nivele
Un microserviciu al aplicat ,iei Planning, are o arhitectur˘ a bazat˘ a pe nivele .ˆIn cadrul
acesteia, elementele software sunt organizate pe straturi (layers) sau nivele. Fiecare
nivel are un set bine definit de responsabilit ˘at,i s,i poate depinde doar de nivelul aflat
imediat sub el. O arhitectur ˘a stratificat ˘a clasic ˘a, cuprinde urm ˘atoarele 3 nivele:
Presentation Layer – cont ,ine cod care implementeaz ˘a interfat ,a cu utilizatorul (UI
– User Interface) sau API-uri externe;
Bussiness Logic Layer – cont ,ine partea de logic ˘a a aplicat ,iei s ,i defines ,te de obicei
o interfat ,˘a sau un registru ( repository ) de interfet ,e care definesc metode de acces
la date;
Data Access Layer – implementeaz ˘a logica interact ,iunii cu baza de date s ,i defines ,te
clasele cu DAO (Data Access Objects), care implementeaz ˘a interfet ,ele din reposi-
tory.
Mai multe detalii despre arhitectura bazat ˘a pe nivele, precum s ,i un exemplu de
implementare ˆın cadrul aplicat ,iei Planning, se ofer ˘aˆın sect ,iunea 4.1.
6

CAPITOLUL 2. FUNDAMENTARE TEORETIC ˘A
2.3 JHipster
JHipster este un tool open-source, folosit la generarea de proiecte pentru aplicat ,ii
web moderne, cu arhitectur ˘a bazat ˘a pe microservicii. La generarea proiectului, pentru
partea de backend, JHipster foloses ,te framework-ul Spring, iar pentru partea de fron-
tend foloses ,te React sau Angular. ˆIntruc ˆat aplicat ,ia client Planning este implementat ˘a
folosind Oracle JET, JHipster a fost folosit doar pentru partea de backend, urm ˆand ca
mai apoi cele dou ˘a part ,i, backend si frontend s ˘a fie integrate.
JHipster permite folosirea unei palete largi de tehnologii ˆın ceea ce prives ,te im-
plementarea backend-ului, a frontend-ului s ,i realizarea deployment-ului. Dup ˘a ce s-au
ales tehnologiile folosite pentru build, baze de date, caching, etc., JHipster va genera
un proiect preg ˘atit s ˘a ruleze ˆın diferite moduri (development, productiv, test), cu fis ,iere
de configurare s ,i fis ,iere cu cod Java [3].
De asemenea, ˆın aplicat ,iile generate cu JHipster, entit ˘at,ile s ,i relat ,iile dintre aces-
tea pot fi descrise simplu s ,iˆıntr-un singur fis ,ier, folosind JHipster Domain Language
(JDL), iar schemele pot fi vizualizate folosind JDL Studio.
2.4 Oracle JET
Oracle JavaScript Extension Toolkit (OJET) este un framework modular de dezvol-
tare al interfet ,elor folosind JavsScript. De asemenea, OJET foloses ,te tehnologii open-
source, cu ajutorul c ˘arora pot fi create interfet ,e complexe.
Figura 2.2: Arhitectura Oracle JET [4]
Oracle JET suport ˘a stilul de proiectare MVVM, ˆın care Modelul cuprinde datele
7

CAPITOLUL 2. FUNDAMENTARE TEORETIC ˘A
aplicat ,iei,View -ul le expune la utilizator, iar ViewModel -ul expune datele Modelului la
View. Arhitectura Oracle JET este reprezentat ˘aˆın figura 2.2.
Pentru a implementa View -ul, Oracle JET ofer ˘a o colect ,ie de componente ˆıncorpo-
rate ca widget-uri jQuery UI , care variaz ˘a de la butoane simple, la popup-uri s ,i la com-
ponente avansate de vizualizare a datelor, cum ar fi tabelele, diagramele s ,i grilele cu
date ( Data Grid ). Explicat ,ii despre cum se folosesc aceste componente s ,i exemple cu
cod, sunt furnizate ˆın Oracle JET Cookbook. ViewModel -ul este implementat folosind
KnockoutJS.
Printre avantajele folosirii OJET se num ˘ar˘a:
– faptul c ˘a ofer ˘a componente UI de validare s ,i convertire a datelor;
– filtrarea s ,i sortarea datelor din Model;
– faciliteaz ˘a rutarea paginilor prin folosirea oj.Router;
– are integrat ˘a autorizarea cu OAuth2 pentru modele provenite de la servicii REST;
– componentele OJET ofer ˘a metode pentru gestionarea evenimentelor;
– legarea datelor ( two-way data binding ) din View s ,i Model folosind Knockout JS ;
– JavaScript logging;
– gestionarea resurselor folosind Require JS ;
– permite realizarea de aplicat ,ii hibride [5].
2.5 jQuery
jQuery este o bibliotec ˘a JavaScript, care simplific ˘a apelurile AJAX (Asynchronous
JavaScript and XML) din JavaScript s ,i manipularea DOM-ului (Document Object Mo-
del). Sintaxa jQuery simplific ˘a traversarea arborilor DOM ( DOM trees ) din HTML, iar
printre funct ,ionalit ˘at,ile pe care le ofer ˘a, se num ˘ar˘a s,i:
– manipularea CSS (Cascading Style Sheets, care descrie cum sunt afis ,are elementele
HTML);
– gestionarea evenimentelor HTML;
– crearea de animat ,ii s ,i efecte;
– implementarea de aplicat ,ii AJAX.
2.6 Require.JS s ,i Knockout.JS
Require.JS este o bibliotec ˘a JavaScript, care ˆıncarc ˘a fis ,iere s ,i gestioneaz ˘a dependen-
t,ele dintre fis ,iere. Este foarte util ˘a deoarece funct ,ioneaz ˘a ca un ˆınc˘arc˘ator modular de
scripturi, cres ,te viteza s ,i calitatea codului.
Knockout.JS este o bibliotec ˘a JavaScript cu ajutorul c ˘areia actualizarea dinamic ˘a
a sect ,iunilor din interfat ,a cu utilizatorul se realizeaz ˘a mai us ,or s ,i mai bine. Avantaje
ale utiliz ˘arii Knockout JS sunt:
8

CAPITOLUL 2. FUNDAMENTARE TEORETIC ˘A
– atunci c ˆand datele din model se modific ˘a, actualizeaz ˘a automat partea de UI cores-
punz ˘atoare;
– utilizare simpl ˘a folosind observables ;
– funct ,ioneaz ˘a cu orice tehnologie de pe partea de client sau server;
– funct ,ioneaz ˘a pe orice browser dintre cele mai cunoscute (Google Chrome, Mozilla
Firefox, Microsoft Edge, Microsoft Internet Explorer, Apple Safari for Mac OS, Apple
Safari for iOS, Opera).
2.7 JS Promises
ECMAScript2017 pune la dispozit ,ie posibilitatea de a utiliza obiecte Promise .
Obiectul Promise reprezint ˘a r˘aspunsul unei operat ,ii asincrone (r ˘aspunsul e reprezen-
tat de rezultatul operat ,ieiˆın cazul ˆın care Promise-ul a fost rezolvat cu succes sau o
eroare ˆın cazul unui es ,ec).
ˆIn aplicat ,ia Planning, am folosit Promises pentru o rezolvare asincron ˘a a cererilor
la server s ,i detectarea erorilor la transmiterea datelor. Am ales s ˘a folosesc Promise-uri
pentru a lucra cu evenimentele asincrone, deoarece acestea pun la dispozit ,ie metode
intuitive ˆın utilizare s ,i care permit ˆınl˘ant ,uirea mai multor metode, iar o metod ˘a este
apelat ˘a doar dac ˘a s-a finalizat execut ,ia tuturor metodelor aflate ˆınainte ei ˆınˆınl˘ant ,uire
(putem astfel controla prelucrarea datelor de c ˘atre procese asincrone), evit ˆand totodat ˘a
intrarea ˆıntr-un Callback Hell .
2.8 Spring Boot
Spring este un framework pentru crearea de aplicat ,ii modulare. El foloses ,te in-
versiunea controlului ( Inversion of Control ), un principiu din ingineria software prin
care controlul obiectelor este transferat ˆıntr-un container. Pentru a implementa acest
principiu, Spring foloses ,te injectarea dependint ,elor ( dependency injection ), un pattern
prin care obiectele sunt conectate ˆıntre ele, sau anumite obiecte sunt injectate ˆın altele.
Spring leag ˘a obiectele pe baza unor anot ˘ari sau pe baza unui fis ,ier XML, astfel toate
obiectele sunt instant ,iate, init ,ializate s ,i injectate ˆın containerele ( bean-urile) potrivite.
Spring Boot ofer ˘a o platform ˘a prin care o aplicat ,ie Spring stand-alone poate fi
creat ˘a s ,i rulat ˘a mai us ,or,ˆıntruc ˆat Spring Boot configureaz ˘a automat aplicat ,ia pe baza
dependent ,elor ad ˘augate utiliz ˆand anot ˘ari. O parte din caracteristicile platformei sunt:
– faptul c ˘a ofer ˘a o modalitate flexibil ˘a de a configura Java Beans;
– gestioneaz ˘a endpoint-urile REST;
– pentru determinarea comportamentului anumitor clase sau metode, se folosesc ano-
t˘ari;
– nu sunt necesare configur ˘ari manuale ˆın fis ,iere XML;
9

CAPITOLUL 2. FUNDAMENTARE TEORETIC ˘A
– dependint ,ele aplicat ,iei sunt gestionate mai eficient;
– simplific ˘a configur ˘arile Maven, care sunt realizate ˆıntr-un fis ,ier POM;
– are Tomcat integrat [6].
2.9 REST API
REST (REpresentational State Transfer) este un stil arhitectural pe baza c ˘aruia se
pot dezvolta servicii web, numite RESTful Web Services . Acestea ofer ˘a serviciilor posi-
bilitatea de a modifica reprezent ˘arile resurselor web folosind anumite operat ,iuni f ˘ar˘a
stare predefinit ˘a s ,i sunt folosite la comunicarea dintre diferitele componente ale unei
aplicat ,ii. Astfel, un REST API este o interfat ,˘a cu ajutorul c ˘areia se trimit cel mai frec-
vent cereri HTTP (de tip GET, PUT, POST, DELETE, CONNECT, PATCH, HEAD, OP-
TIONS sau TRACE) ˆıntre componente. Cerea se face c ˘atre un URI ( Uniform Resource
Identifier ) al unei resurse s ,i r˘aspunsul cont ,ine un antet ( header ), cu informat ,ii despre
mesajul transmis (vezi figura 4.10) s ,i corpul mesajului ( body ), care cont ,ine datele trans-
mise ˆın format JSON, XML, etc. Prin folosirea unui REST API, componentele nu se
influent ,eaz˘a reciproc s ,i pot fi implementate folosind tehnologii diferite, trebuie doar
s˘a se cunoasc ˘a formatul mesajelor care vor fi schimbate ˆıntre componente.
ˆIn cazul aplicat ,iei Planning, REST API se foloses ,te la transmiterea datelor ˆıntre
microservicii s ,iˆıntre aplicat ,ia client s ,i microservicii.
2.10 Liquibase
Liquibase este o bibliotec ˘a, care permite urm ˘arirea s ,i gestionarea modific ˘arilor
efectuate asupra bazei de date, f ˘ar˘a a le pierde. Aceasta realizeaz ˘a un changelog pentru
schema bazei de date, adic ˘aˆınregistreaz ˘a modific ˘arile care au avut loc ˆın baza de date
s,i le stocheaz ˘aˆın fis ,iere XML, JSON, SQL sau YAML.
Liquibase permite dezvoltatorului de software s ˘a aplice modific ˘ariˆın schem ˘a, s˘a
o actualizeze sau s ˘a o aduc ˘a la o versiune anterioar ˘a prin intermediul changelog-urilor,
f˘ar˘a s˘a fie nevoie de comenzi SQL manuale. Dup ˘a ce se face o modificare ˆın schema
bazei de date, la rulare, Liquidbase va urm ˘ari daca changelog-ul adaugat a fost rulat,
iarˆın caz contrar, aplic ˘a modific ˘arile indicate ˆın fis ,ier s ,i adaug ˘a un nou element ˆın
tabela databasechangelog ,ˆımpreun ˘a cu un checksum MD5 pentru cont ,inutul lui.
2.11 Hibernate s ,i JPA
Hibernate ORM (Object/Relational Mapping), este o unealt ˘a folosit ˘aˆın aplicat ,iile
Java la maparea entit ˘at,ilor din domeniu, la obiecte din baza de date relat ,ional ˘a. De
asemenea, Hibernate ajut ˘a aplicat ,ia s˘a aib ˘a date persistente, adic ˘a starea obiectelor
10

CAPITOLUL 2. FUNDAMENTARE TEORETIC ˘A
s˘a r˘amˆan˘a aceeas ,i s,iˆın afara JVM (Java Virtual Machine), pentru a putea fi folosit ˘a
oricˆand.
Cele mai importante avantaje ale folosirii Hibernate sunt urm ˘atoarele:
– mapeaz ˘a tipurile de date din Java la tipuri de date SQL;
– mapeaz ˘a clase Java la tabele din baza de date;
– suport ˘alazy loading (datele obiectelor mos ,tenite se ˆıncarc ˘a odat ˘a cu datele obiectului
p˘arinte doar daca se cere explicit acest lucru);
– genereaz ˘a o mare parte din SQL la momentul init ,ializ ˘arii aplicat ,iei, nu la momentul
rul˘arii;
– poate fi us ,or configurat s ,i extins;
– este us ,or de scalat.
2.12 Stream API
Stream API a fost introdus ˆın Java 8 s ,i este folosit pentru a gestiona colect ,ii de
obiecte. Un stream este o secvent ,˘a de obiecte care accept ˘a metode ce pot fi configurate
pentru a produce un anumit rezultat.
O parte din caracteristicile stream-urilor Java sunt:
– un stream nu este o structur ˘a de date, ci un obiect care preia colect ,ii, vectori, etc.;
– nu modific ˘a structura de date de la care primes ,te datele, ci pe baza metodelor folosite
returneaz ˘a rezultate;
– operat ,iile intermediare realizate returneaz ˘a stream-uri, de aceea acestea pot fi ˆınl˘an-
t,uite;
– operat ,iile terminale marcheaz ˘a finalul stream-ului s ,i returneaz ˘a rezultatele.
Operat ,iile care pot fi realizate intermediar sunt: map ,filter s,isorted , iar cele
terminale sunt: forEach ,collect s,ireduce .
2.13 Alte tehnologii
Pentru procesul de build al aplicat ,iei, am folosit Maven . Configur ˘arile, dependen-
t,ele s ,i plugin-urile aplicat ,iei se afl ˘aˆın POM (Project Object Model), care e un fis ,ier
XML. Pe baza fis ,ierului POM, Maven descarc ˘a bibliotecile necesare aplicat ,iei s ,i le sto-
cheaz ˘a local. Maven poate rula teste JUnit s ,i poate genera Javadoc, iar un alt mare
avantaj e acela c ˘a t,ine seama de dependent ,ele tranzitive (daca o dependent ,˘a depinde
de alte surse, nu trebuie s ˘a ne facem griji pentru celelalte surse, ˆıntruc ˆat Maven le des-
carc˘a s,i pe acelea).
Pentru stocarea datelor care sunt frecvent utilizate, am folosit unealta open-source
Hazelcast . Acesta este o gril ˘a cu date in-memory folosit ˘aˆın procesul de caching .
Ca baz ˘a de date am ales s ˘a folosesc Oracle SQL deoarece este una dintre cele mai
11

CAPITOLUL 2. FUNDAMENTARE TEORETIC ˘A
puternice s ,i extensibile platforme SQL. Pe l ˆang˘a faptul c ˘a poate gestiona cu us ,urint ,˘a
cantit ˘at,i mari de date, ofer ˘a suport pentru tehnologiile de virtualizare, ofer ˘a strategii
de scalare, iar infrastructura de lansare a aplicat ,ieiˆın mediul productiv era deja reali-
zat˘a.
12

3 Descriere general˘ a a aplicat ,iei
Planning a fost g ˆandit ˘a ca o aplicat ,ie modular ˘a, cu componente slab cuplate, sca-
labil ˘a, us ,or de lansat s ,i ment ,inut s ,i care s ˘a fie folosit ˘aˆın ret ,ea de mai mult ,i angajat ,i
ai unei companii. De aceea, stilul arhitectural ales este cel bazat pe microservicii . Fiecare
microserviciu are o arhitectur ˘a structurat ˘a pe nivele ( layered architecture ).
3.1 Aplicat ,ia Planning
Aplicat ,ia are o structur ˘a bazat ˘a pe microservicii frontend s ,i backend.
Figura 3.1: Arhitectura bazat ˘a pe microservicii a aplicat ,iei Planning (inspirat din: [2])
Microserviciile frontend includ o interfat ,˘a web pentru utilizator (Planning Web
UI) s ,i un API Gateway (Application Programming Interface Gateway). Planning Web
UI implementeaz ˘a interfat ,a web care este folosit ˘a de utilizatori pentru a face plani-
fic˘arile, iar Gateway-ul furnizeaz ˘a un REST API s ,i ruteaz ˘a cererile client ,ilor la serviciile
corespunz ˘atoare. Fiecare microserviciu backend (Employee Microservice s ,i Planning
13

CAPITOLUL 3. DESCRIERE GENERAL ˘A A APLICAT ,IEI
Microservice) expune c ˆate un REST API s ,i are o baz ˘a de date privat ˘a (Employee DB,
respectiv Planning DB). Microserviciul Employee furnizeaz ˘a date legate de zilele li-
bere legale, vacant ,ele solicitate de angajat ,iti s ,i tipul lor de contract, iar microserviciul
Planning expune prin API-ul REST informat ,ii legate de disponibilitatea s ,i planific ˘arile
angajat ,ilor.
Aplicat ,ia Planning client cont ,ine 2 pagini: pagina Planning (cu planific ˘arile unui
angajat s ,iˆın care s ,eful departamentului ˆıl poate planifica ˆın continuare) s ,i pagina Over-
view ( ˆın care e afis ,at num ˘arul de zile neplanificate al angajat ,ilor per departament). Ru-
tarea paginilor din aplicat ,ie am implementat-o astfel ˆıncˆat atunci c ˆand planificatorul
se afl ˘a pe pagina Overview s ,i observ ˘a c˘a o persoan ˘a are zile neplanificate, s ˘a poat ˘a
da click pe numele persoanei s ,i s˘a fie direct ,ionat automat spre pagina Planning cores-
punz ˘atoare persoanei, iar atunci c ˆand apas ˘a butonul ”Back”, s ˘a fie trimis la pagina de
Overview anterioar ˘a.
Din punct de vedere al interfet ,ei cu utilizatorul, pagina Planning cont ,ine urm ˘atoa-
rele componente:
Grila cu date:
–ˆın grila cu date se prezint ˘a planific ˘arile angajatului selectat; header-ul din
partea de sus a grilei e ˆımp˘art ,itˆın trimestre, luni s ,i coloane corespunz ˘atoare
duratei s ,i efortului depus de angajat, iar header-ul din partea st ˆang˘a a grilei
eˆımp˘art ,itˆın client ,i s,i proiecte;
–grila se poate afla ˆın dou ˘a moduri: modul de editare al duratei s ,i modul de
editare al eficient ,ei s ,i permite navigarea ˆıntre celule folosind tastele cu s ˘aget ,i
ale tastaturii;
–toate celulele de pe coloana corespunz ˘atoare duratei, respectiv a eficient ,ei,
sunt editabile, iar apasarea tastei enter dup ˘a introducerea unei valori, deter-
min˘a apelarea serviciului care salveaz ˘a valoarea ˆın baza de date s ,i calculeaz ˘a
efortul depus de angajat, acesta fiind apoi afis ,atˆın celula alaturat ˘a;
–valoarea pentru durat ˘a trebuie s ˘a fie un num ˘ar mai mic sau egal cu 50, cu
maxim 2 cifre s ,i o zecimal ˘a, iar valoarea pentru eficient ,˘a trebuie s ˘a fie un
num ˘ar mai mic sau egal cu 1, cu 2 zecimale; dac ˘a valorile introduse sunt
gres ,ite, apare un mesaj de avertisment;
–apasarea tastei tab trimite focusul pe urm ˘atoarea celul ˘a editabil ˘a de pe r ˆandul
curent, iar dac ˘a nu mai exist ˘a celule editabile pe r ˆandul curent, focusul trece
pe prima celul ˘a de pe r ˆandul urm ˘ator;
–efortul depus de un angajat se calculeaz ˘a ca produs ˆıntre durat ˘a s,i eficient ,˘a
dac˘a eficient ,a de baz ˘a e 1, altfel la produs se ˆınmult ,es,te s ,i eficient ,a de baz ˘a;
14

CAPITOLUL 3. DESCRIERE GENERAL ˘A A APLICAT ,IEI
–pe ultimul r ˆand al grilei este afis ,at totalul zilelor r ˘amase neplanificate pentru
fiecare lun ˘a; fiecare celul ˘a de pe ultimul r ˆand are o culoare stabilit ˘aˆın funct ,ie
de cˆate zile sunt neplanificate din num ˘arul de zile disponibile;
–pe ultima coloan ˘a a grilei este afis ,at totalul zilelor planificate pentru un anu-
mit proiect relativ la perioada selectat ˘a;
–este afis ,at˘a s,i o legend ˘a a culorilor.
Butoane pentru navigare:
–exist ˘a dou ˘a butoane pentru navigarea ˆıntre planific ˘arile angajat ,ilor din de-
partamentul selectat;
–alte dou ˘a butoane sunt folosite la navigarea cu o jum ˘atate de an (respectiv
un an pentru pagina Overview) ˆınainte s ,iˆınapoi ˆıntre planific ˘arile angajatu-
lui selectat;
–exist ˘a s,i un buton ”Filter” care deschide un canvas din partea st ˆang˘a a ecra-
nului; acesta poate fi deschis s ,i la ap ˘asarea tastelor CTRL+ALT+F.
Canvasul:
–cuprinde un LOV (List Of Values), adic ˘a o list ˘a cu departamentele de dezvol-
tare software ale companiei; selectarea unui departament determin ˘a popu-
larea celui de-al doilea LOV cu angajat ,ii de pe departamentul respectiv;
–o component ˘a calendar care permite selectarea unui interval de timp pentru
care s ˘a fie afis ,ate planific ˘arile;
–un LOV care permite selectarea tipului de grid: duration (poate fi editat ˘a
durata planificat ˘a) sau efficiency (se editeaz ˘a eficient ,a angajatului ˆın funct ,ie
de timpul petrecut ˆın c˘al˘atorii).
Pe baza id-ului utilizatorului, componentele OJET se populeaz ˘a automat cu date
ˆın funct ,ie de nis ,te valori prestabilite: dac ˘a utilizatorul e s ,ef de departament de dezvol-
tare, departamentul selectat este departamentul s ˘au, planific ˘arile afis ,ate sunt cele ale
primului angajat din departament, iar intervalul de timp corespunde anului curent.
Similar cu pagina Planning, pagina Overview cont ,ine o gril ˘a care are coloanele
ˆımpˆart ,iteˆın trimestre s ,i luni, iar pe r ˆanduri sunt numele angajat ,ilor din departamentul
selectat. Celulele grilei nu sunt editabile, iar fiecare celul ˘a afis ,eaz˘a num ˘arul total de
zile planificate pentru un angajat ˆın luna corespunz ˘atoare. Acestea sunt colorate tot
comparativ cu num ˘arul total de zile disponibile. Aceast ˘a pagin ˘a cont ,ine butoane de
navigate ˆıntre intervale de timp s ,i alte butoane pentru navigarea ˆıntre departamente.
Prezint ˘a, de asemenea, un buton pentru deschiderea unui canvas, care cont ,ine un LOV
cu departamente s ,i o component ˘a calendar.
15

CAPITOLUL 3. DESCRIERE GENERAL ˘A A APLICAT ,IEI
16

4 Detalii de proiectare s ,i implementare
4.1 Arhitectura microserviciului Planning
Figura 4.1: Arhitectura microserviciului Planning
Cu toate c ˘a arhitectura unui microserviciu este structurat ˘a pe nivele, la baza aces-
teia se afl ˘a modelul client-server, iar transferul de date dintre client s ,i server se reali-
zeaz ˘a cu ajutorul protocolului HTTP , folosind stilul arhitectural REST.
Dup ˘a cum se observ ˘aˆın figura 4.1, serverul este alc ˘atuit din cele 3 nivele de baz ˘a
descrise ˆın sect ,iunea 2.2. Cererile clientului sunt preluate de Rest Controller din Pre-
sentation Layer , sunt procesate la nivel de Business Logic Layer cu ajutorul serviciilor s ,iˆın
funct ,ie de datele solicitate efectueaz ˘a operat ,ii pe baza de date prin intermediul obiec-
telor de accesare a datelor (DAO) din Data Access Layer , implementate folosind JPA
(Java Persistence API). Transferul de date este bidirect ,ional, iar ca r ˘aspuns la cererea
f˘acut ˘a, clientul primes ,te fie un mesaj de eroare, fie datele solicitate.
Mai multe detalii despre fiecare layer, componentele lor s ,i felul ˆın care acestea
interact ,ioneaz ˘a, vor fi descrise ˆın sect ,iunea 4.2.
17

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
4.2 Componentele microserviciului Planning
Figura 4.2: Componentele microserviciului Planning [7]
4.2.1 Nivelul de prezentare a datelor
Acest nivel este implementat cu ajutorul framework-ului Spring MVC , deci este
organizat pe baza arhitecturii Model-View-Controller (MVC).
Componenta central ˘a a Spring MVC este DispatcherServlet s,i reprezint ˘a unul din-
tre modelele de design Java EE de baz ˘a, numite controler frontal. C ˆand DispatcherSer-
vlet primes ,te o cerere HTTP , va c ˘auta mai ˆıntˆai un handler adecvat care s ˘a se ocupe de
aceasta. Dac ˘a decide c ˘a nu este necesar s ˘a fie procesate informat ,ii pe Business Logic
Layer, prin ViewResolver va r ˘aspune direct cu View-ul corespunz ˘ator [7]. HandlerMa-
pping este responsabil pentru returnarea unui handler adecvat pentru o cerere. Un
handler este un obiect Java care poate gestiona cererile web. Handler-ul tipic folo-
sit pentru gestionarea cererilor web este un Controller . Controler-ul trebuie s ˘a invoce
servicii back-end pentru manipularea cererilor.
Dintre toate componentele din Presentation Layer, programatorul trebuie s ˘a im-
plementeze doar partea de View s ,i cea de Controler, celelalte fiind implementate de
framework.
18

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Figura 4.3: Interact ,iunea dintre componentele arhitecturii
ˆIn cazul aplicat ,iei Planning, ˆın pachetul com.virtual7.planning.web.rest se afl ˘a
resursele, adic ˘a acele clase care implementeaz ˘a endpoint-urile REST (adic ˘a referint ,e
la URI-uri care accept ˘a cereri REST la anumite resurse). O resurs ˘a este anotat ˘a cu
@RestController, deci Spring Boot va percepe resursa ca pe un controler RESTful web
service , adic ˘a nu se foloses ,te de o tehnologie de select ,ie de view-urilor, ci pur s ,i simplu
r˘aspunde cu un obiect, ale c ˘arui c ˆampuri pot fi scrise direct ˆın r˘aspunsul HTTP ca
JSON [6]. Prin anotarea @RequestMapping, clasa trateaz ˘a cererile HTTP la URL-ul
dat de @RequestMapping. Exist ˘a s ,i anot ˘ari specifice (@GetMapping, @PutMapping,
@PostMapping, @DeleteMapping) cu ajutorul c ˘arora se determin ˘a tipul cererii s ,i care
este metoda ce r ˘aspunde acelei cereri.
1@RestController
2@RequestMapping ( ”/api/v1” )
3public c l a s s BupResourcePlanningResource f
4 . . .
5 @GetMapping ( ”/bup resourceplannings ” )
6 public ResponseEntity <L is t<BupResourcePlanningDTO > >
getAllBupResourcePlannings ( Pageable pageable ) f
7 log . debug ( ”REST request to get a page of BupCustomers” ) ;
8 . . .
9 return ResponseEntity . ok ( ) . headers ( headers ) . body ( page . getContent ( ) ) ;
10g
11g
Secvent ,a de cod 4.1: Exemplu anotare controler
Un controler preia JSON-ul transmis ˆın corpul ( body ) cererii HTTP sub form ˘a de
DTO, foloses ,te unul sau mai multe servicii pentru a prelucra datele s ,i returneaz ˘a un
DTO (mai multe detalii despre servicii s ,i DTO-uri sunt oferite ˆın sect ,iunea 4.2.2).
19

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
4.2.2 Nivelul de business logic
Acest nivel sust ,ine ideea de aplicat ,ie modular ˘a,ˆıntruc ˆat decupleaz ˘a partea de
preluare a cererilor s ,i cea de operare direct ˘a pe baza de date. Astfel, accesul la baza de
date se face prin intermediul interfet ,elor din componenta Repository.
Componenta Service descrie felul ˆın care datele sunt create, transmise s ,i sto-
cate. ˆIn pachetul com.virtual7.planning.service se afl ˘a clase anotate cu @Service, in-
dicˆandu-se astfel c ˘a acestea cont ,in partea de business logic a microserviciului. Un ser-
viciu primes ,te la intrare un DTO, ˆın cadrul metodelor acesta e transformat ˆın entitate
(DAO), apeleaz ˘aEntityRepository pentru a face diferite operat ,ii cu entit ˘at,ile respective
(vezi metoda save() de mai jos) s ,i returneaz ˘a tot un DTO, pentru c ˘a mai departe acesta
e transmis prin REST endpoint clientului. Clasele care reprezint ˘a DTO-urile, se g ˘asesc
ˆın pachetul com.virtual7.planning.dto .
1@Service
2@Transactional
3public c l a s s BupResourcePlanningService f
4 . . .
5 public BupResourcePlanningService (
6 BupResourcePlanningRepository bupResourcePlanningRepository ,
7 BupResourcePlanningMapper bupResourcePlanningMapper ) f
8 t h i s . bupResourcePlanningRepository = bupResourcePlanningRepository ;
9 t h i s . bupResourcePlanningMapper = bupResourcePlanningMapper ;
10g
11
12 public BupResourcePlanningDTO save (
13 BupResourcePlanningDTO bupResourcePlanningDTO ) f
14 BupResourcePlanning bupResourcePlanning =
15 bupResourcePlanningMapper . t o E n t i t y ( bupResourcePlanningDTO ) ;
16 bupResourcePlanning =
17 bupResourcePlanningRepository . save ( bupResourcePlanning ) ;
18 return bupResourcePlanningMapper . toDto ( bupResourcePlanning ) ;
19g
20 . . .
21g
Secvent ,a de cod 4.2: Implementare a serviciului pentru BupResourcePlanning
Un DTO este o reprezentare a unei entit ˘at,i din domeniu, cuprinde c ˆampuri pri-
vate care cont ,in date, gettere, settere s ,i constructori. Un DAO este chiar entiatea, care
ˆıncapsuleaz ˘a datele s ,i logica de primire, s ,tergere s ,i modificare a datelor din baza de
date. Trecerea aceasta de la DTO la DAO s ,i invers, se realizeaz ˘a folosind mappere (clase
utilizate la mapare) aflate ˆın pachetul com.virtual7.planning.service.mapper . Realizez
aceast ˘a conversie pentru a nu expune la client anumite date. De exemplu, poate DAO
cont ,ine s ,i salariul unui angajat s ,i nu as ,vrea s ˘a fie transmis la client, as ,a c˘a folosind
maparea, ˆın DTO voi avea un obiect care nu cont ,ine atributul salary.
20

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Un mapper mai e folosit ˆın cadrul aplicat ,iei s ,i pentru a combina mai multe en-
tit˘at,iˆıntr-un singur DTO. De exemplu, un BupCustomerDTO cont ,ine o list ˘a de Bu-
pProjectDTO, iar un BupProjectDTO cont ,ine o list ˘a de BupResourcePlanningDTO. De
asemenea, dac ˘a DTO-ul (sau entitatea) cont ,ine un c ˆamp care nu e primitiv, framework-
ul poate s ˘a gestioneze astfel de structuri complexe, prin intermediul map ˘arii realizate
prin ad ˘augarea atributului uses ˆın cadrul anot ˘arii @Mapper. Mai jos este dat ca exem-
plu mapper-ul pentru BupCustomer.
1@Mapper ( componentModel = ” spring ” , uses = fBupProjectMapper . c l a s sg)
2public i n t e r f a c e BupCustomerMapper extends
3 EntityMapper <BupCustomerDTO , BupCustomer >f
4 @Mapping ( t a r g e t = ” p r o j e c t s ” )
5 BupCustomerDTO toDto ( BupCustomer customerDTO ) ;
6
7 default BupCustomer fromId ( Long id ) f
8 i f( id == null )f
9 return null ;
10g
11 BupCustomer bupCustomer = new BupCustomer ( ) ;
12 bupCustomer . s e t I d ( id ) ;
13 return bupCustomer ;
14g
15g
Secvent ,a de cod 4.3: Implementarea map ˘arii pentru BupCustomer
4.2.3 Nivelul de accesare a datelor
Componenta Repository este corespunz ˘atoare pachetului com.virtual7.planning
.repository s,i cont ,ine interfet ,ele anotate cu @Repository. Acestea extind clasa JP ARe-
pository , care are nevoie s ˘a i se specifice numele entit ˘at,ii cu care lucreaz ˘a un anumit
Repository s ,i tipul cheii primare corespunz ˘atoare din baza de date. Aici sunt imple-
mentate operat ,ii CRUD (CREATE, READ, UPDATE s ,i DELETE).
1@Repository
2public i n t e r f a c e BupResourcePlanningRepository extends JpaRepository <
BupResourcePlanning , Long >f
3 L is t<BupResourcePlanning >findResourcePlanning (
4 @Param ( ”employeeId” ) Long employeeId ,
5 @Param ( ” s t a r t D a t e ” ) I n s t a n t startDate ,
6 @Param ( ”endDate” ) I n s t a n t endDate ) ;
7 . . .
8g
Secvent ,a de cod 4.4: Implementarea BupResourcePlanningRepository
Pot fi scrise interog ˘ari JPA (anotate cu @Query) pentru baza de date, ˆıns˘a
framework-ul permite s ,i o generare automat ˘a de interog ˘ari JPA pe baza unor metode,
21

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
daca se respect ˘a anumite reguli atunci c ˆand se stabiles ,te numele metodelor. Spre exem-
plu, metoda findResourcePlanning() , care aduce o planificare de la baza de date, cores-
punde unei interog ˘ari de forma celei din secvent ,a de cod 4.5.
1SELECT rp FROM BupResourcePlanning rp WHERE rp . employee . id = : employeeId
A N D rp . s t a r t D a t e . id = : s t a r t D a t e I d A N D rp . endDate . id = : endDateId .
Secvent ,a de cod 4.5: Exemplu query
Sunt folosite query-uri JPA pentru c ˘a se lucreaz ˘a cu obiectele din domeniu, nu
direct cu tabele.
Componenta Entity este corespunz ˘atoare pachetului com.virtual7.planning.do-
main , care cont ,ine entit ˘at,ile anotate cu @Entity, specific ˆandu-se astfel c ˘a acestea sunt
clasele care opereaz ˘a direct cu baza de date. Prin anotarea @Table se specific ˘a tabelul pe
care opereaz ˘a o anumit ˘a entitate. Relat ,iile dintre tabele se specific ˘a folosind anot ˘arile
@OneToOne, @OneToMany, @ManyToMany, plasate deasupra c ˆampurilor prin inter-
mediul c ˘arora se stabiles ,te relat ,ia. Exist ˘a s ,i anot ˘ari prin care se stabilesc reguli sau
restrict ,ii pentru anumite c ˆampuri ale entit ˘at,ii. De exemplu, ˆın secvent ,a de cod 4.6,
pentru c ˆampul plannedYear se specific ˘a faptul c ˘a nu poate fi null (prin anotarea @Not-
Null) s ,i corespunde coloanei planned year din baza de date (prin anotarea @Column).
1@Entity
2@Table ( name = ” bup resource planning ” )
3@Cache ( usage = CacheConcurrencyStrategy . NONSTRICT READ WRITE)
4public c l a s s BupResourcePlanning implements S e r i a l i z a b l e f
5 . . .
6 @NotNull
7 @Column(name = ” planned year ” , n u l l a b l e = f a l s e )
8 private I n t e g e r plannedYear ;
9 . . .
10 // g e t t e r s and s e t t e r s
11g
Secvent ,a de cod 4.6: Implementarea entit ˘at,ii BupResourcePlanning
Pentru stocarea datelor, microserviciile folosesc c ˆate o baz ˘a de date Oracle SQL.
Diagramele bazelor de date vor fi prezentate s ,i detaliate ˆın sect ,iunea 4.3.
4.3 Baza de date
Aplicat ,ia Planning poate rula cu 3 profile: dev (development) s ,i test, profile ˆın
care am folosit o baz ˘a de date in-memory s,i prod (production), care foloses ,te o baz ˘a de
date Oracle SQL, ˆımpreun ˘a cu JPARepository.
Pentru testare am ales s ˘a folosesc o baz ˘a de date in-memory (ˆımpreun ˘a cu Java Per-
sistence API (JPA) s ,i Hibernate), s ,i anume H2 database , deoarece nu necesit ˘a configurare
s,i mentenant ,˘a,ˆıntruc ˆat baza de date in-memory este creat ˘a cand pornes ,te aplicat ,ia s ,i
22

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
s,tears ˘a cand aplicat ,ia e oprit ˘a. Totodat ˘a baza de date H2 dispune de o interfat ,˘a web
(disponibil ˘a la adresa http://localhost:8080/h2-console ), ceea ce o face s ,i mai us ,or de folo-
sit. Pentru baza de date in-memory, Spring Boot parcurge entit ˘at,ile s ,i creaz ˘a implicit
tabelele s ,i baza de date. ˆIn schimb, daca e vorba de baza de date Oracle SQL, ˆın mod
implicit se as ,teapt ˘a ca baza de date s ,i tabelele s ˘a fie configurate s ,i s˘a fie utilizat ˘a cone-
xiunea stabilit ˘a.
Configurarea bazei de date H2 pentru profilul dev, se g ˘ases ,teˆın fis ,ierul application-
dev.yml , unde am setat s ,iJBDC url , username s ,i parola pentru a m ˘a putea conecta la
aceasta (vezi secvent ,a de cod 4.7). De asemenea, determinarea portului pentru cone-
xiunea la H2 database se realizeaz ˘aˆın clasa DatabaseConfiguration , pentru care se ac-
tiveaz ˘a s ,i JPARepositories prin anotarea @EnableJpaRepositories(”com.virtual7.planning
.repository”) .
1datasource :
2 u r l : jdbc : h2 : f i l e : . / t a r g e t /h2db/db/planning
3 username : planning
4 password :
5 jpa :
6 databaseplatform : io . github . j h i p s t e r . domain . u t i l . FixedH2Dialect
7 database : H2
8 . . .
Secvent ,a de cod 4.7: Configurare H2 database pentru profilul dev
Configurarea basei de date Oracle SQL pentru profilul prod, am f ˘acut-o ˆın fis ,ierul
application-dev.yml , unde am setat portul, username s ,i parola pentru baza de date Plan-
ning (secvent ,a de cod 4.8). ˆIn mod similar se configureaz ˘a bazele de date s ,i pentru
microserviciul Employee.
1datasource :
2 type : com . zaxxer . h i k a r i . HikariDataSource
3 u r l : jdbc : o r a c l e : thin : @localhost :1522/ pdb1
4 username : r i c
5 password : psswd
6 jpa :
7 databaseplatform : org . hibernate . d i a l e c t . O r a c l e 1 2 c D i a l e c t
8 database : ORACLE
9 . . .
Secvent ,a de cod 4.8: Configurare Oracle database pentru profilul prod
ˆIntruc ˆat am folosit JHipster ca tool pentru generarea aplicat ,iei, a fost necesar s ˘a
specific schema bazei de date utilizate, ˆın fis ,ierul planning-jdl.jhi , folosind JHipster Do-
main Language (JDL). Diagramele bazelor de date ˆın JDL s ,i dependint ,ele dintre tabele
sunt reprezentate ˆın figurile 4.4 s ,i 4.5. De asemenea, pentru gestionarea modific ˘arilor
asupra entit ˘at,ilor JDL, JHipster foloses ,te Liquibase, care ret ,ine modific ˘arile efectuate
ˆın fis ,ierele XML aflate ˆın pachetul src/main/resources/config/liquibase/changelog .
23

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Figura 4.4: Diagrama bazei de date planning ˆın JDL
24

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Figura 4.5: Diagrama bazei de date employee ˆın JDL
25

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Baza de date a microserviciului Planning cont ,ine urm ˘atoarele tabele:
– bup resource planning: cont ,ine toate planific ˘arile angajat ,ilor;
– bup assigned resources: cu ajutorul acestei tabele sunt asociate proiecte la anumit ,i
angajat ,i;
– bup project: aceast ˘a tabel ˘a asociaz ˘a proiectele corespunz ˘atoare la anumit ,i client ,i
– bup customer: cont ,ine numele s ,i id-urile tuturor client ,ilor
– bup objectives: ret ,ine obiectivele pentru un angajat ˆın fiecare quarter; obiectivul pe
un an este QUARTER = 5;
– sp entry: asociaz ˘a la un proiect de la un anumit client, informat ,ii legate de buget-ul
pentru acel proiect (pentru departamentul de V ˆanz˘ari);
– sp entry resource: leag ˘a o planificare a v ˆanz˘arilor la o resurs ˘a, care ar putea fi un
angajat sau un text liber (NAME) dac ˘a resursa nu este ˆınc˘a o entitate cunoscut ˘a sau
dac˘a resursa e extern ˘a;
– sp month: valorile lunare de planificare Man Days s,iˆın valut ˘a (EUR)
– sp quarter: calculat automat din sp month.
Baza de date a microserviciului Employee cont ,ine urm ˘atoarele tabele:
– employees: cont ,ine datele despre toti angajat ,ii;
– country: asociaz ˘a fiec ˘arui angajat t ,ara din care face parte (din cauz ˘a c˘a zilele libere
legale difer ˘a de la t ,ar˘a la t ,ar˘a);
– legal vacation: asociaz ˘a zilele libere legale pentru fiecare t ,ar˘a
– departments: asociaz ˘a la fiecare departament angajat ,ii corespunz ˘atori;
– vacation requests: cont ,ine cererile pentru concedii s ,i tipurile acestora pentru fiecare
angajat;
– vacation type: stocheaz ˘a tipurile de concedii pentru cererile f ˘acute de fiecare angajat;
– request status: starea ˆın care se afl ˘a fiecare cerere de concediu;
– approovers: cont ,ine persoanele delegate s ˘a accepte sau nu cererile de concediu pen-
tru fiecare angajat s ,i departament;
– vacation: cont ,ine date despre vacant ,ele acceptate pentru fiecare angajat;
– emp contract worktime: cont ,ine date despre contractul unui angajat (tipul contrac-
tului);
– split contract dow: specific ˘a pentru un anumit contract (dac ˘a angajatul nu lucreaz ˘a
de luni p ˆan˘a vineri) num ˘arul de zile ˆın care angajatul lucreaz ˘a.
26

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
4.4 Aplicat ,ia client Planning
Aceast ˘a component ˘a reprezint ˘a de fapt partea vizual ˘a a aplicat ,iei s ,i a fost imple-
mentat ˘a folosind JavaScript s ,iframework-ul Oracle JET . Structura acestei componente se
bazeaz ˘a pe stilul arhitectural Model-View-ViewModel (MVVM), ˆın care componenta
software este ˆımp˘art ,it˘a dupa cum se observ ˘aˆın figura 4.6: Modelul reprezint ˘a datele
aplicat ,iei,ViewModel expune date din Model la View s ,i ment ,ine starea aplicat ,iei, iar cu
ajutorul View -ului se reprezint ˘a clientului datele.
Figura 4.6: Descrierea arhitecturii MVVM [4]
ˆIn cadrul aplicat ,iei Planning, partea de frontend se afl ˘aˆın directorul src/main/web-
app-ojet/src/js/planning de pe Gateway . Aplicat ,ia web cuprinde 4 pachete:
– services: parte din componenta MODEL din figur ˘a, cont ,ine fis ,ierele planningServi-
ces.js s,ioverviewServices.js , cu funct ,ii de tip get, put, post s ,i delete, care returneaz ˘a
Promise-uri, care la r ˆandul lor apeleaz ˘a resursele REST din servere;
– views: pachet corespunz ˘ator componetei VIEW din figur ˘a, cont ,ine fis ,iere HTML, deci
reprezentarea vizual ˘a a componentelor OJET din pagin ˘a;
– viewModels: parte a componentei VIEW/MODEL, cont ,ine fis ,iere javascript cu me-
tode, evenimente, funct ,ii observable s ,i observableArray;
– uimodels: pachet corespunz ˘ator componentei MODEL, cont ,ine clase care grupeaz ˘a
observables cu date referitoare la o anumit ˘a component ˘a (echivalent ˘a unei entit ˘at,i din
partea de server); tot aici am definit s ,i clasele folosite la generarea gridului.
Mai multe detalii despre arhitectura Oracle JET s ,i felul ˆın care componentele aces-
teia interact ,ioneaz ˘a, sunt oferite ˆın sect ,iunea 2.4.
27

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
4.4.1 Generarea gridului cu date
Reprezentarea vizual ˘a a datelor legate de angajat ,i s,i planific ˘arile lor, am imple-
mentat-o folosind componenta ojDataGrid (vezi secvent ,a de cod 4.9), care permite
vizualizarea pe mai multe nivele ˆın funct ,ie de felul ˆın care au fost generate antelele gri-
lei, navigarea ˆıntre celulele grilei, preluarea s ,i modificarea caracteristicilor unei celule
din grid sau din header folosind cellContext , respectiv headerContext .
1<ojdatagrid id= ’ datagrid ’
2 data= ’ [ [ data ] ] ’ // in o b s e r v a b i l u l ’ data ’ corespunzator din f i s i e r u l
j a v a s c r i p t sunt s t o c a t e d a t e l e cu care va f i populat gridul
3 editmode= ’ c e l l N a v i g a t i o n ’ // se permite navigarea i n t r e c e l u l e
4 onojbeforee d i t = ’ [ [ handleEdit ] ] ’
5 onojbeforeeditend= ’ [ [ handleEditEnd ] ] ’
6 header . column . renderer= ’ [ [ columnHeaderRenderer ] ] ’
7 header . row . label . renderer= ’ [ [ labelRenderer ] ] ’
8 header . row . s t y l e = ’ [ [ rowHeaderStyleHandler ] ] ’
9 header . row . renderer= ’ [ [ rowHeaderRenderer ] ] ’
10 header . column . s t y l e = ’ [ [ columnHeaderStyleHandler ] ] ’
11 c e l l . renderer= ’ [ [ getCellTemplate ] ] ’
12 c e l l . s t y l e = ’ [ [ c e l l S t y l e H a n d l e r ] ] ’ >
13</ojdatagrid>
Secvent ,a de cod 4.9: Componenta oj-data-grid din Planning
Pentru a crea gridul, nu a fost suficient s ˘a folosesc cele 3 obiecte indicate de Ora-
cle JET Cookbook:
– NestedCellSet (seteaz ˘a indecs ,ii fiec ˘arei celule din grid pe baza unor metode predefi-
nite ca getCount(), getStart(), getExtent(), etc);
– NestedHeaderSet (seteaz ˘a indecs ,ii fiec ˘arei celule din header, similar cu clasa anteri-
oar˘a);
– NestedHeaderDataGridDataSource (preia date de la cele 2 clase amintite anterior
s,i creaz ˘a gridul pe baza lor), ci am creat ˆınc˘a un obiect, UIPlanningDataGridModel ,
ˆıntruc ˆat a fost nevoie s ˘a stabilesc prin intermediul s ˘au, pozit ,ia datelor ˆın celulele din
grid (vezi figura 4.7). Acest obiect foloses ,te un algoritm prin care am stocat ierarhic
datele ˆın array-uri: datele legate de trimestre-luni-zile sunt stocate ˆınthis.quarters , iar
cele legate de client ,i-proiecte-angajat ,i sunt stocate ˆınthis.customers (vezi secvent ,a de
cod 4.10).
1define ( [ ’ o j s / o j c o r e ’ , ’ o j s /o j a r r a y d a t a g r i d d a t a s o u r c e ’ ] ,
2 function ( o j ) f
3 // constante
4 return c l a s s UIPlanningDataGridModel f
5 c o n s t r u c t o r ( data , editType , businessDays , startDate , endDate ) f
6 t h i s . startDateValue = startDateValue ;
7 t h i s . endDateValue = endDateValue ;
8 t h i s . qu arte rs = t h i s . createQuartersArray ( ) ;
28

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
9 t h i s . customers = t h i s . createCustomersArray ( data ) ;
10 t h i s . colsNumber = t h i s . getNumberOfColumns ( ) ;
11 t h i s . rowsNumber = t h i s . getNumberOfRows ( ) ;
12 t h i s . colHeaders = t h i s . createColumnHeaders ( ) ;
13 t h i s . rowHeaders = t h i s . createRowHeaders ( ) ;
14 t h i s . grid = t h i s . fillGridWithPlanningData ( ) ;
15 t h i s . totalColumnIndex = t h i s . colsNumber2 ;
16 t h i s . totalRowIndex = t h i s . rowsNumber1 ;
17 g
18 // implementarea f u n c t i i l o r
19g;
20g) ;
Secvent ,a de cod 4.10: Metodele clasei UIPlanning
Obiectul UIPlanningDataGridModel este folosit ˆın fis ,ierul planning.js pentru obt ,i-
nerea vectorilor cu date, a num ˘arului de r ˆanduri, de coloane pentru grid, pentru cre-
area indecs ,ilor celulelor din headere, date care sunt folosite de NestedHeaderDataGrid-
DataSource pentru crearea gridului. Acesta este stocat ˆın observabilul self.data , necesar
componentei oj-data-grid dinplanning.html (vezi secvent ,a de cod de mai jos).
1s e l f . displayDataGrid = function ( data ) f
2 gridModel = new UIPlanningDataGridModel ( data , s e l f . editType , s e l f .
businessDays , s e l f . startDateValue ( ) , s e l f . endDateValue ( ) ) ;
3 s e l f . data ( new NestedHeaderDataGridDataSource (
4 gridModel . rowsNumber , gridModel . colsNumber ,
5 gridModel . quarters , gridModel . customers , gridModel . grid ,
6 gridModel . rowHeaders , gridModel . colHeaders ) ) ;
7g;
Secvent ,a de cod 4.11: Afis ,area gridului cu date ˆın pagina Planning
Diagrama de clase s ,i interact ,iunea dintre componentele paginii Planning, poate
fi vizualizat ˘aˆın figura 4.7.
4.4.2 Obt,inerea efortului depus de un angajat
ˆIntre Client s ,i Server, datele sunt transmise prin intermediul protocolului HTTP
REST, sub forma de mesaje JSON. Pentru o rezolvare asincron ˘a a cererilor la server s ,i
detectarea erorilor la transmiterea datelor, am folosit obiecte javascript Promise . Obiec-
tul Promise reprezint ˘a r˘aspunsul unei operat ,ii asincrone (r ˘aspunsul e reprezentat de
rezultatul operat ,ieiˆın cazul ˆın care Promise-ul a fost rezolvat cu succes sau o eroare ˆın
cazul unui es ,ec). Am ales s ˘a folosesc Promise-uri pentru a lucra cu evenimentele asin-
crone, deoarece acestea pun la dispozit ,ie metode intuitive ˆın utilizare s ,i care permit
ˆınl˘ant ,uirea mai multor evenimente asincrone, evit ˆand astfel intrarea ˆıntr-un Callback
Hell.
29

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Figura 4.7: Interact ,iunea dintre componentele paginii Planning
30

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Pentru a face o cerere la server de pe partea de frontend, am folosit s ,i biblioteca
request.js , implementat ˘aˆın cadrul companiei s ,i care pune la dispozit ,ie metode pentru
simplificarea cererilor de tipul GET, PUT, POST, DELETE. Spre exemplu, metoda getP()
(vezi secvent ,a de cod 4.12), preia ca parametru un URI care reprezint ˘a un endpoint ˆın
spatele c ˘aruia se afl ˘a un serviciu REST s ,i cu ajutorul unui apel jQuery AJAX (metoda
ajax() e folosit ˘a pentru cereri HTTP asincrone), returneaz ˘a un Promise GET care cont ,ine
s,i purt ˘atorul de autorizare dac ˘a tokenul exist ˘a.ˆIn cadrul metodei ajax() se seteaz ˘a pa-
rametrii header-ului, tipul datelor din body, tipul cererii s ,i url-ul (pentru un exemplu
de header, vezi imaginea 4.10).
1s e l f . getP = function ( u r l ) f
2 i f( s e l f . authTokenExpired ( ) ) f
3 return Promise . r e j e c t ( new Error ( ” e r r . token . expired ! ” ) ) ;
4g
5 var getPromise = $ . a j a x ( f
6 u r l : s e l f . u r l ( u r l ) ,
7 type : ”GET” ,
8 contentType : s e l f . JSON CONTENT TYPE,
9 headers : s e l f . getGloablRequestHeader ( ) ,
10 dataType : ” json ”
11g) ;
12 return s e l f . toPromise ( getPromise ) ;
13g;
Secvent ,a de cod 4.12: Metoda cu ajutorul c ˘areia se fac cererile GET la server
Atunci c ˆand planificatorul editeaz ˘a o celul ˘a corespunzatoare coloanei ”Duration”,
la server se trimite un JSON cu valoarea introdus ˘aˆın grid de utilizator, printr-un
POST la URI-ul ”planning/v1/bup-resource-plannings/:employeeId/:projectId” , iar
ca r˘aspuns serverul va trimite la client un JSON, care cont ,ine Efortul calculat ˆın funct ,ie
de tipul de contract s ,i num ˘arul de zile disponibile ˆıntr-o anumit ˘a lun ˘a pentru acel an-
gajat. Funct ,ia cu ajutorul c ˘areia se face POST-ul se afl ˘aˆın fis ,ierul planningServices.js s,i
returneaz ˘a un Promise care cont ,ine valoarea efortului calculat (vezi secvent ,a 4.13).
1define ( [ ’ knockout ’ , ’ jquery ’ , ’ v i r t u a l 7 /request ’ , ’ lodash ’ , ’ promise ’ ] ,
2 function ( ko , $ , req , )f
3 function PlanningServices ( ) f
4 . . .
5 s e l f . postDuration = function ( employeeId , p r o j e c t I d , postData ) f
6 var postUrl = req . tokenUrl (POST DURATION, [
7 ftoken : ” : employeeId” , value : employeeId g,
8 ftoken : ” : p r o j e c t I d ” , value : p r o j e c t I d g
9 ] ) ;
10 return req . postP ( postUrl , postData )
11 . then ( ( data ) = >f
12 o j . Logger . i n f o ( ” Retrieved the e f f o r t ” , data ) ;
13 return Promise . r e s o l v e ( data ) ;
31

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
14 g) ;
15 g;
16g
17 return new PlanningServices ( ) ;
18g) ;
Secvent ,a de cod 4.13: Funct ,ia care preia efortul s ,iˆıl returneaz ˘aˆıntr-un Promise
ˆIntruc ˆat funct ,ia anonim ˘a din fis ,ierul planningServices.js returneaz ˘a un obiect Plan-
ningServices, fis ,ierul este dat ca parametru ˆınplanning.js , astfel ˆıncˆat s˘a poat ˘a fi apelate
serviciile prin intermediul s ˘au (vezi secvent ,a de cod 4.14).
1s e l f . g e t E f f o r t = function ( p r o j e c t I d , postData ) f
2 return s e l f . pServices
3 . postDuration ( s e l f . selectedEmployee ( ) , p r o j e c t I d , postData ) ;
4g;
Secvent ,a de cod 4.14: Funct ,ia din view care apeleaz ˘a serviciul
Preluarea valorii efortului pentru a putea fi scris ˘aˆın grid, am implementat-o ˆın
funct ,ia utilitar ˘ahandleEditEnd.js (pus ˘a la dispozit ,ie de framework prin intermediul
obiectului oj.DataCollectionEditUtils.basicHandleEditEnd ), care se apeleaz ˘a auto-
mat atunci c ˆand s-a terminat editarea unei celule din grid (vezi secvent ,a de cod 4.15).
1s e l f . g e t E f f o r t ( p r o j e c t . id , postData )
2 . then ( ( postResponse ) = >f
3 //toFixed ( ) to round to one decimal place
4 //p a r s e F l o a t ( ) to remove decimals l e f t by toFixed ( )
5 r e c e i v e d E f f o r t = postResponse . e f f o r t ;
6 e f f o r t = p a r s e F l o a t ( r e c e i v e d E f f o r t . toFixed ( 1 ) ) ;
7 gridModel . grid [ cellRow ] [ cellColumn + 1] = ”” + e f f o r t ;
8 gridModel . g e t T o t a l ( cellColumn , cellRow ) ;
9 s e l f . refreshDataGrid ( ) ;
10 s e l f . goToNextEditableCell ( cellRow , cellColumn ) ;
11g)
12 .catch ( ( reason ) = >f
13 s e l f . e r r . computeError ( reason ) ;
14g) ;
Secvent ,a de cod 4.15: Scrierea valorii efortului ˆın grid
Pe ramura then() se preia r ˘aspunsul serviciului, valoarea efortului, care este rot-
unjit ˘a s ,i scris ˘a pe pozit ,ia potrivit ˘aˆın matricea corespunz ˘atoare gridului ( grid[][] ) din
modelul construit prin intermediul obiectului UIPlanningDataGridModel . Dup ˘a re-
alizarea acestei operat ,ii, grid-ul este re ˆımprosp ˘atat pentru a afis ,a noua valoare a efor-
tului s ,i este setat s ˘a treac ˘a focusul pe urmatoarea celul ˘a editabil ˘a (urm ˘atoarea coloan ˘a
”Duration”).
32

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
4.4.3 Rutarea paginilor
Aplicat ,iilesingle page necesit ˘a o rutare s ,i navigare diferite fat ,˘a de aplicat ,iile web
tradit ,ionale. Acestea actualizeaz ˘a adresa URL pentru a reflecta starea ˆın care se afl ˘a
aplicat ,ia la un moment dat s ,i pentru a actualiza istoricul browserului. ˆIn Oracle Ja-
vaScript Extension Toolkit (OJET) exist ˘a mecanismul de a face rutarea prin oj.Router,
ˆıns˘a din cauz ˘a c˘a am avut nevoie s ˘a stochez ˆın URL mai mult ,i parametrii, utilizarea a
devenit greoaie. O aplicat ,ie tipic ˘a OJET are un sistem principal de navigare s ,i de ru-
tare, iar acest lucru ajut ˘a utilizatorul s ˘a navigheze prin paginile (modulele) aplicat ,iei.
Fiecare modul care necesit ˘a stocarea st ˘ariiˆın URL va trebui s ˘a implementeze routerele
copil ( child routers ) [8]. ˆIn cazul meu, cum num ˘arul de parametrii care trebuiau stocat ,i
ˆın URL varia de la pagina de Planning la cea de Overview (vezi figurile 4.8 s ,i 4.9), ar fi
trebuit ca pentru fiecare parametru care trebuie stocat ˆın URL s ˘a creez un child router
folosind Router.rootInstance.createChildRouter , iar pentru c ˘a un router poate avea
un singur child router, acestea trebuiau s ˘a fie ˆınl˘ant ,uite.
Figura 4.8: Parametrii din URL pentru pagina Planning
Figura 4.9: Parametrii din URL pentru pagina Overview
Ca solut ,ie, am creat o clas ˘a utilitar ˘a numit ˘aRoutingUtils , care realizeaz ˘a ruta-
rea pentru orice pagin ˘a cu numar variabil de parametrii ˆın URL. Pentru a folosi clasa
utilitar ˘a,ˆın fis ,ierul javascript al paginii pentru care se face rutarea, trebuie adaugat
un array care cont ,ine obiecte cu 3 atribute: name (numele parametrului), type (tipul
parametrului), observable (cont ,ine un obserbale knockoutJS care stocheaza starea cu-
rent˘a a child router-ului), apoi trebuie apelat ˘a funct ,iainitRouters() din clasa utilitar ˘a.
Clasa oj.Router dispune de funct ,iatransitionedToState , care gestioneaz ˘a tranzit ,ia de
la o stare la alta. Acest eveniment poate fi folosit s ,i pentru a identifica modificarea
33

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
valorii pentru un parametru URL, deci aici am stocat noua valoare a parametrului ˆın
observable-ul corespunz ˘ator, iar acesta re ˆımprosp ˘ateaz ˘a automat pagina datorit ˘a me-
canismului de legare ( binding ).
4.5 Comunicarea inter-server
Pentru ca microserviciul Planning s ˘a preia de la microserviciul Employee date
legate de concedii, zile libere legale s ,i tip de contract, am folosit OpenFeign , un client
HTTP oferit de Netflix .
1<dependency >
2 <groupId >org . springframework . cloud </groupId >
3 <a r t i f a c t I d >springclouds t a r t e ropenfeign </a r t i f a c t I d >
4</dependency >
Secvent ,a de cod 4.16: Dependent ,a Maven pentru OpenFeign
Pentru a permite ca Spring Boot s ˘a identifice clientul Feign, am adaugat anota-
rea @EnableFeignClients ˆın clasa de configurare a acestuia s ,i am setat nivelul logului
pentru a ˆınregistra cererile REST ale clientului (vezi secvent ,a de cod 4.17).
1@Configuration
2@EnableFeignClients ( basePackages = ”com . v i r t u a l 7 . planning ” )
3public c l a s s FeignConfiguration f
4 @Bean
5 f e i g n . Logger . Level feignLoggerLevel ( ) f
6 return f e i g n . Logger . Level . BASIC ;
7g
8g
Secvent ,a de cod 4.17: Configurarea clientului Feign
Clasele s ,i interfat ,a corespunzatoare clientului Feign se g ˘asesc ˆın pachetul com.vir-
tual7.planning.client . Aici am creat o interfat ,˘a anotat ˘a cu @AuthorizedFeignClient
(pentru a fi recunoscut ˘a de Spring Boot ca s ,i client Feign s ,i pentru a fi configurat ˘a s˘a se
autentifice cu OAuth2 ˆın cazul comunic ˘arii inter-server), ˆın care am specificat metoda
cu care microserviciul Planning va prelua date de la microserviciul Employee, pe care
am mapat-o la URI-ul corespunz ˘ator din Employee (secvent ,a de cod 4.18).
1@AuthorizedFeignClient ( name = ”employee” , f a l l b a c k = EmployeeClientFallback
.c l a s s )
2public i n t e r f a c e EmployeeClient f
3 @GetMapping ( ”/api/v1/departments/ fidg/dev/employees” )
4 L is t<SimpleEmployeesDTO >getDepartmentDevEmployees ( @RequestParam ( ” id ” )
Long depId ) ;
5g
Secvent ,a de cod 4.18: Interfat ,a clientului Feign
34

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Aceast ˘a metod ˘a am apelat-o ˆın clasa BupAggregatedPlanningResource ,ˆın care este
implementat algoritmul de preluarea a planific ˘arilor agregate pentru angajat ,ii unui
anumit departament, ˆın pagina de Overview. De asemenea, clientul Feign este confi-
gurat s ˘a trimit ˘a r˘aspuns de eroare ˆın cazurile c ˆand URI-ul este gres ,it, timpul de r ˘aspuns
a expirat sau vectorii cu datele despre concedii, zile libere legale sau tipul de contract,
nu cont ,in informat ,ii.
Pentru a se realiza autentificarea s ,i autorizarea pentru situat ,iaˆın care microservi-
ciile Employee s ,i Planning comunic ˘a, am folosit obiectul OAuth2InterceptedFeignConfi-
guration , care ia ca parametru un obiect AuthorizationHeaderUtil s,i returneaz ˘a un obiect
TokenRelayRequestInterceptor cu un parametru de tipul precizat anterior.
1public c l a s s TokenRelayRequestInterceptor implements RequestInterceptor f
2 . . .
3 @Override
4 public void apply ( RequestTemplate template ) f
5 Optional <String >authorizationHeader = authorizationHeaderUtil .
getAuthorizationHeaderFromOAuth2Context ( ) ;
6 i f( authorizationHeader . i s P r e s e n t ( ) ) f
7 template . header (AUTHORIZATION, authorizationHeader . get ( ) ) ;
8g
9 // t r i m i t s i id token l a server pentru a obtine a u t o r i z a r e a
10 Optional <String >idTokenHeader = getIdTokenFromUserDetails ( ) ; //
preia id token din s e c u r i t y context
11 i f( idTokenHeader . i s P r e s e n t ( ) ) f
12 template . header (ID TOKEN , idTokenHeader . get ( ) ) ;
13g
14g
15g
Secvent ,a de cod 4.19: Realizarea autoriz ˘arii folosind interceptorul
Atunci c ˆand se face o cerere de la un microserviciu c ˘atre alt microserviciu, Feign
aplic ˘a interceptorul prin care se construies ,te un request template , care se aplic ˘a la
cererea f ˘acut ˘a. Astfel toate serviciile care sunt executate prin Feign (server-to-server),
au aplicat un template pentru fiecare request, cu c ˆate un header de OAuth care cont ,ine
idtoken, necesar autoriz ˘arii (vezi secvent ,a de cod 4.19).
4.6 Implementarea serviciilor REST
Transmiterea datelor ˆıntre client s ,i server se realizeaz ˘a prin intermediul protoco-
lului HTTP folosind stilul arhitectural REST, iar datele transmise sunt grupate ˆın partea
de header a cererii/r ˘aspunsului sub form ˘a de JSON (vezi figura 4.10).
ˆIn funct ,ie de tipul cererii (GET, PUT, POST, DELETE), status -ul r ˘aspunsului va fi
fie 200 (Status OK), fie 201 (Created), fie 400 (Bad Request). Pentru a detecta c ˆand un
35

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Figura 4.10: Exemplu de header
endpoint nu poate fi transmis ca o referint ,˘a URI, fiecare metod ˘a din pachetul com.virtu-
al7.planning.web.rest arunc ˘a o except ,ie de tipul URISyntaxException. De asemenea,
ˆın pachetul com.virtual7.planning.web.rest.errors , se afl ˘a clase implementate pen-
tru gestionarea diferitelor erori care pot ap ˘area ˆın timpul comunic ˘arii dintre client
s,i server: BadRequestAlertException ,InternalServerErrorException ,InvalidPasswordExcep-
tion,LoginAlreadyUsedException ,FieldErrorVM ,ErrorConstants ,ExceptionTranslator (clas ˘a
anotat ˘a cu @ControllerAdvice, care translateaz ˘a except ,iile care apar pe partea de ser-
ver,ˆıntr-o structur ˘a JSON ce poate fi ˆınt ,eleas ˘a de client), CustomParameterizedException .
Clasa din urm ˘a, creaz ˘a except ,ii parametrizate, care pot fi translatate pe partea de client.
De exemplu, secvent ,a:
1throw new CustomParameterizedException ( ’ myCustomError ’ , ’ h e l l o ’ , ’ world ’ ) ;
poate fi translatat ˘aˆın
1” e r r o r . myCustomError” : ”The server says ffparam0ggtoffparam1gg”
De asemenea, pentru crearea header-elor HTTP se foloses ,te clasa HeaderUtils din
pachetul com.virtual7.planning.web.utils , iar pentru gestionarea pagin ˘arii se foloses ,te
clasa PaginationUtils din acelas ,i pachet.
4.6.1 Generarea planific˘ arilor pentru angajat,i
Pentru popularea gridului cu informat ,iile necesare legate de client ,ii la care a lu-
crat un angajat ˆın perioada selectat ˘a, proiectele la care a fost asignat s ,i planific ˘arile pen-
tru proiectele respective, am creat ˆın pachetul com.virtual7.planning.web.rest o me-
tod˘a care e mapat ˘a la URI-ul api/v1/bup-resource-plannings/employeeId/startDate
/endDate . Endpoint-ul are ca parametrii id-ul angajatului din baza de date, data de
ˆınceput a planific ˘arii s ,i cea de sf ˆars ,it, iar ˆın cazul ˆın care transmiterea datelor s-a reali-
36

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
zat cu succes, r ˘aspunsul serviciului este 200 s ,i o list ˘a cu toate planific ˘arile angajatului
din perioada selectat ˘a. Deoarece pentru generarea JSON-ului de r ˘aspuns am avut ne-
voie doar de informat ,ii de la tabelele BupCustomer, BupProject, BupAssignedResour-
ces s ,i BupResourcePlanning, tabele care se reg ˘asesc ˆın baza de date a microserviciului
Planning, nu a fost nevoie de o comunicare inter-server ˆıntre microserviciile Planning
s,i Employee.
JSON-ul are o structur ˘a ierarhizat ˘a, astfel ˆıncˆat datele s ˘a fie us ,or de preluat ˆın
grid: pe primul nivel se afl ˘a un vector de client ,i, fiecare client cont ,ine un vector cu
proiecte, iar fiecare proiect cont ,ine pe lang ˘a alte date, un vector cu planific ˘ari. Fie-
care planificare cont ,ine id-ul resursei asignate, anul s ,i luna corespunz ˘atoare, durata de
timp planificat ˘a, eficient ,a angajatului s ,i efortul caculat s ,i pe baza eficient ,ei de baz ˘a din
tabela cu resurse asignate. ˆIn acest sens am creat un obiect numit EmployeePlanning,
care s ˘a cont ,in˘a un vector cu client ,ii la care e asignat.
Entitatea JPA BupResourcePlanning (care reprezint ˘a o planificare) este mapat ˘a
la tabela bup resource planning s,i cont ,ine un c ˆamp de tipul BupAssignedResources,
corespunz ˘ator tabelei bup assigned resources (deci exist ˘a o dependent ,˘a one-to-one
ˆıntre cele 2 tabele, prin care se specific ˘a proiectul asignat fiecarui angajat, precum s ,i
atributul baseEfficiency , folosit la calculul efortului depus de angajat). Similar, o entiate
BupCustomer cont ,ine o list ˘a de entit ˘at,i BupProject (mapare many-to-one ˆın tabele),
care la r ˆandul s ˘au cont ,ine o list ˘a de BupResourcePlanning. Cele dou ˘a liste sunt anotate
cu @Transient pentru c ˘a nu sunt persistente ˆın baza de date.
Pentru a prelua planific ˘arile de la server, am creat mai ˆıntˆai un obiect de tipul Em-
ployeePlanning, apoi am preluat client ,ii, proiectele, resursele asignate s ,i planific ˘arile,
cu ajutorul serviciilor corespunz ˘atoare s ,i pe baza parametrilor din URI. Mai departe
algoritmul e descris ˆın secvent ,a de cod de mai jos 4.20).
1@GetMapping ( ”/bup resourceplannings /femployeeIdg/fs t a r t D a t eg/fendDateg” )
2public ResponseEntity <EmployeePlanningDTO >getEmployeePlannings ( . . . preiau
v a r i a b i l e l e din header . . . ) throws ParseException f
3 . . .
4 // Preiau c l i e n t i i , p r o i e c t e l e , r e s u r s e l e a s i g n a t e s i p l a n i f i c a r i l e
5 // Parcurg c l i e n t i i s i l e asignez p r o i e c t e l e corespunzatoare
6 customers . forEach ( customer >f
7 L is t<BupProjectDTO >customerProjects = p r o j e c t s
8 . stream ( )
9 // f i l t r e z c l i e n t i i dupa id
10 . f i l t e r ( p>Objects . equals ( p . getCustomerId ( ) , customer . getId ( )
) )
11 . c o l l e c t ( C o l l e c t o r s . t o L i s t ( ) ) ;
12 // s e t e z p r o i e c t e l e f o l o s i n d metoda s e t P r o j e c t s ( ) din CustomerDTO
13 customer . s e t P r o j e c t s ( customerProjects ) ;
14g) ;
15 // Similar , parcurg r e s u r s e l e asignate , l e at as ez p r o i e c t e l e s i gasesc
37

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
p l a n i f i c a r i l e corespunzatoare , in plus , pentru f i e c a r e p l a n i f i c a r e
c a l c u l e z e f o r t u l ca produs d i n t r e e f i c i e n t a , durata s i e f i c i e n t a de baza
16 // Atasez c l i e n t i i o b i e c t u l u i de t i p u l EmployeePlanningDTO c r e a t s i i l
returnez ca raspuns a l s e r v i c i u l u i
17 employeePlanning . setCustomers ( customers ) ;
18 return ResponseUtil . wrapOrNotFound ( Optional . ofNullable ( employeePlanning
) ) ;
19g
Secvent ,a de cod 4.20: Generarea planific ˘arilor pentru un angajat
ˆIntruc ˆat am f ˘acut maparea dintre DTO-uri s ,i entit ˘at,i, crearea ierarhiei din JSON
se va crea automat pe baza componentelor fiec ˘arui obiect (4.2.2).
4.6.2 Deducerea num˘ arului de zile ˆ ın care un angajat e disponibil
Pentru a calcula num ˘arul de zile ˆın care un angajat e disponibil, am creat un algo-
ritm care foloses ,te mai multe filtre pentru a exclude dintr-un interval de timp dat, zilele
libere legale, zilele de concediu s ,i calculeaz ˘a disponibilitatea angajatului ˆın funct ,ie de
tipul s ˘au de contract. Algoritmul calculeaz ˘a corect zilele disponibile s ,i pentru cazul ˆın
care intervalul de timp e ˆımpart ,itˆın ani diferit ,i (trebuie s ˘a fie aduse din baza de date
informat ,iile referitoare la vacant ,e s,i tip de contract pentru tot ,i anii pe care se ˆıntinde
intervalul) sau angajatul lucreaz ˘a doar anumite zile din sapt ˘amˆan˘a.
ˆIntruc ˆat num ˘arul zilelor disponibile ale angajatului se calculeaz ˘a pe baza date-
lor din tabelele LegalVacation, VacationRequests, EmpContractWorktime s ,i SplitCon-
tractDow, aflate ˆın baza de date a microserviciului Employee, am implementat servi-
ciul ˆın cadrul acestui microserviciu. Init ,ial am ˆıncorporat partea de calcul a zilelor
disponibile ale angajatului ˆın JSON-ul generat de serviciul descris ˆın sect ,iunea ante-
rioar ˘a,ˆıns˘a am constatat c ˘a era o solut ,ie ineficient ˘a, deoarece se realiza o comuni-
care inter-server (vezi sect ,iunea 4.5) ori de c ˆate ori microserviciul Planning avea ne-
voie de date de la Employee. Astfel operat ,ia de aducere a zilelor libere, pentru c ˘a
se realiza pentru fiecare angajat ˆın parte, devenea foarte consumatoare de timp. De
aceea, serviciul care cont ,ine algoritmul de calcul al zilelor disponibile se afl ˘aˆın pa-
chetul com.virtual7.employee.web.rest , iar ˆın diagrama de secvent ,˘a 4.11 se observ ˘a
interact ,iunea dintre clasele implicate ˆın algoritm. Totodat ˘a, din interact ,iunea clase-
lor se poate deduce s ,i organizarea pe nivele a acestora (datorit ˘a arhitecturii bazate pe
nivele, discutat ˘a laˆınceputul acestui capitol): serviciile sunt apelate de controlere, iar
acestea preiau la r ˆandul lor date din repositories, care ˆıncapsuleaz ˘a datele preluate de
la baza de date.
38

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Figura 4.11: Diagrama de secvent ,˘a pentru calculul disponibilit ˘at,ii unui angajat
39

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
4.6.3 Generarea num˘ arului de zile neplanificate pentru un angajat,ii
dintr-un departament
Calcularea num ˘arului de zile afis ,atˆın celulele gridului din pagina de overview,
se realizeaz ˘a pe baza operat ,iei:num˘ ar zile disponibile – num˘ ar de zile planificate (pentru o
anumit ˘a lun ˘a), operat ,ie realizat ˘a pe partea de frontend dup ˘a prealuarea datelor de la
servicii. Pentru obt ,inerea celor 2 valori necesare efectu ˘arii calculului, am avut nevoie
de 2 servicii: unul care s ˘a furnizeze num ˘arul de zile disponibile ale angajat ,ilor ac-
tivi dintr-un departament ˆıntr-un anumit interval de timp s ,i un altul care s ˘a furnizeze
num ˘arul total de zile planificate pentru fiecare angajat dintr-un departament ˆıntr-un
interval de timp.
Num ˘arul de zile disponibile ale angajat ,ilor activi dintr-un departament ˆıntr-un
anumit interval de timp, le-am preluat direct de la microserviciul Employee, prin
endpoint-ul employee/api/v1/business-days/department/depId/startDate/endDate .
Pentru a obt ,ine num ˘arul total de zile planificate pentru fiecare angajat dintr-un depar-
tament ˆıntr-un interval de timp, am implementat un serviciu accesibil la endpoint-ul
planning/api/v1/bup-aggregated-plannings/depId/startDate/endDate .ˆIn acest sens,
am preluat datele despre angajat ,ii departamentului dat de depId , prin intermediul cli-
entului Feign (comunicare inter-server), employeeClient , de la endpoint-ul employee/a-
pi/v1/departments/id/dev/employees .
1@AuthorizedFeignClient ( name = ”employee” , f a l l b a c k =
2 EmployeeClientFallback . c l a s s )
3public i n t e r f a c e EmployeeClient f
4 @GetMapping ( ”/api/v1/departments/ fidg/dev/employees” )
5 L is t<SimpleEmployeesDTO >getDepartmentDevEmployees ( @RequestParam ( ” id ” )
Long depId ) ;
6g
Secvent ,a de cod 4.21: Preluarea datelor despre angajat ,i prin clientul Feign
De asemenea, am implementat creat o entitate ˆın domain numit ˘aBupAggregated-
Planning , care furnizeaz ˘a num ˘arul total de zile planificate pentru un anumit angajat s ,i
are constructorul de mai jos 4.22.
1public BupAggregatedPlanning ( Long employeeId , I n t e g e r plannedMonth , I n t e g e r
plannedYear , Double totalPlanning , Double t o t a l P l a n n e d A v a i l a b i l i t y ) f
2 t h i s . employeeId = employeeId ;
3 t h i s . plannedMonth = plannedMonth ;
4 t h i s . plannedYear = plannedYear ;
5 i f( t o t a l P l a n n i n g != null )f
6 t h i s . t o t a l P l a n n i n g = t o t a l P l a n n i n g . f l o a t V a l u e ( ) ;
7g
8 i f( t o t a l P l a n n e d A v a i l a b i l i t y != null )f
9 t h i s . t o t a l P l a n n e d A v a i l a b i l i t y = t o t a l P l a n n e d A v a i l a b i l i t y .
f l o a t V a l u e ( ) ;
40

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
10g
11g
Secvent ,a de cod 4.22: Entitatea BupAggregatedPlanning
De asemenea, prin intermediul clasei BupAggregatedPlanningService , se pune la
dispozit ,ie serviciul de preluare al tuturor planific ˘arilor pentru un angajat, ˆıntr-un in-
terval de timp dat. Serviciul este folosit mai apoi ˆın metoda getAggregatedPlannings()
din resursa corespunz ˘atoare, mapat ˘a la endpoint-ul planning/api/v1/bup-aggregated-
plannings/depId/startDate/endDate (vezi secvent ,a de cod 4.23).
1public ResponseEntity <OverviewPlanningDTO >getAggregatedPlannings
2 ( . . . preiau v a r i a b i l e l e din header . . . ) f
3 . . .
4 // Preiau t o a t e p l a n i f i c a r i l e a n g a j a t i l o r ( din i n t e r v a l u l de timp dat )
din departamentul s e l e c t a t
5 L is t<BupAggregatedPlanningDTO >sumPlannings=
bupAggregatedPlanningService
6 . getAggregatedPlannings ( startDate , endDate ) ;
7 // Preiau a n g a j a t i i departamentului cu Feign
8 L is t<SimpleEmployeesDTO >employees =employeeClient
9 . getDepartmentDevEmployees ( depId ) ;
10 OverviewPlanningDTO overviewPlanning = new OverviewPlanningDTO ( ) ;
11 // Setez departamentul s i a n g a j a t i i din DTO
12 DepartmentsDTO department = new DepartmentsDTO ( ) ;
13 department . s e t I d ( depId ) ;
14 department . setEmployees ( employees ) ;
15 // Pentru f i e c a r e a n g a j a t a l departamentului , f i l t r e z din t o a t e
p l a n i f i c a r i l e doar pe c e l e corespunzatoare l u i s i i l e a t r i b u i in DTO
16 employees . forEach ( empl >f
17 L is t<BupAggregatedPlanningDTO >aggrPlanning = sumPlannings
18 . stream ( )
19 . f i l t e r ( plannings >Objects . equals ( plannings . getEmployeeId ( ) ,
empl . getId ( ) ) ) . c o l l e c t ( C o l l e c t o r s . t o L i s t ( ) ) ;
20 empl . setAggregatedPlanning ( aggrPlanning ) ;
21g) ;
22 L is t<DepartmentsDTO >departments = new ArrayList <>() ;
23 departments . add ( department ) ;
24 // Setez in o b i e c t u l overviewPlanning t o a t e departamentele cu d a t e l e
acumulate despre a n g a j a t i s i i l returnez
25 overviewPlanning . setDepartments ( departments ) ;
26 return ResponseUtil . wrapOrNotFound ( Optional . ofNullable ( overviewPlanning
) ) ;
27g
Secvent ,a de cod 4.23: Generarea planific ˘arilor agregate
41

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
4.7 Autentificarea s ,i autorizarea
Pentru a implementa mecanismul de autentificare OAuth2 a aplicat ,iei cu Micro-
soft Azure, am folosit libr ˘aria open source Spring Starter for Azure Active Directory
(vezi secvent ,a de cod 4.24). ˆIn cadrul mecanismului, se folosesc 3 tipuri de token-
uri: id token (arat ˘a identitarea utilizatorului), access token (indic ˘a daca utilizatorul
are access la un anumit API; daca nu are, trebuie folosit id token pentru a primi un ac-
cess token) s ,i refresh token (prelunges ,te valabilitatea unui access token dup ˘a ce acesta
expir ˘a). De asemenea, pentru securizarea aplicat ,iei, am folosit framework-ul Spring Se-
curity .
1<dependency >
2 <groupId >com . microsoft . azure </groupId >
3 <a r t i f a c t I d >azureac ti vedirectoryspringboots t a r t e r </a r t i f a c t I d >
4 <version >2.0.5</ version >
5</dependency >
Secvent ,a de cod 4.24: Dependent ,a Maven pentru Spring Starter for AAD
Figura 4.12: Etapele mecanismului de autentificare s ,i autorizare [9]
42

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
Mecanismul se realizeaz ˘aˆın 3 etape: logarea utilizatorului cu credent ,ialele sale s ,i
validarea id token-ului la Azure Active Directory , obt ,inerea token-ului de acces la Azure
AD Graph API s,i evaluarea permisiunilor, bazat ˘a pe informat ,iile de acces primite (vezi
figura 4.12).
ˆIn cazul unei aplicat ,ii Spring Boot, se creaz ˘a automat un lant ,de filtre de secu-
ritate, autentificare, redirect ,ionare, etc. Pentru autentificarea la un microserviciu, a
fost creat un filtru (clasa AADMicroservicesAuthenticationFilter din pachetul com.virtu-
al7.planning.aad.filter ), care a fost ad ˘augat ˆın lant ,ul de filtre, dup ˘a filtrul de autentifi-
care pentru a avea acces la id token s ,i access token.
1@Component
2public c l a s s AADMicroservicesAuthenticationFilter extends
AADAuthenticationFilter f
3 . . .
4 @Override
5 protected void d o F i l t e r I n t e r n a l (
6 . . .
7 S t r i n g idToken = request . getHeader (ID TOKEN) ;
8 i f( idToken != null && ! idToken . isEmpty ( ) ) f
9 i f( environment . a c c e p t s P r o f i l e s ( ”prod” ) ) f
10 AADUserGrantedAuthorities userGrantedAuthorities =
11 userGroupService . getUserGrantsFromAAD ( idToken ) ;
12 userGroupService . se tGr an tsI nS ec uri ty Con te xt ( idToken ,
13 userGrantedAuthorities ) ;
14 g
15g
16 f i l t e r C h a i n . d o F i l t e r ( request , response ) ;
17g
18g
Secvent ,a de cod 4.25: Filtrul de autentificare pentru microserviciul Planning
Aici preiau id token trimis de Gateway din header-ul cererii, iar dac ˘a profilul ˆın
care ruleaz ˘a aplicat ,ia este production , obt ,in un alt access token. Cu ajutorul lui s ,i al
id-ului companiei virtual7, accesez Microsoft Graph API, care pe baza id token-ului
furnizeaz ˘a din Azure Active Directory, grupurile la care are acces utilizatorul. Aceste
grupuri sunt inserate apoi ˆınSecurity Context , astfel ˆıncˆat s˘a funct ,ioneze mecanismul
de securitate din Spring Boot. Configurarea Microsoft AAD s-a f ˘acut ˆın fis ,ierul appli-
cation.yml , unde e specificat s ,i id-ul Microsoft Azure al companiei pentru identificarea
Active Directory corespunz ˘ator s ,i grupurile din Active Directory necesare aplicat ,iei
(vezi secvent ,a de cod 4.26).
43

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
1azure :
2 a c t i v e d i r e c t o r y :
3 tenantid : 117 a3859xxxxxxxxxxxxxxxxxxxxxx
4 ac ti vedirectorygroups : PLANNING USER, PLANNING EDITOR
5 c l i e n tid : e080d109xxxxxxxxxxxxxxxxxxxxxx
6 c l i e n ts e c r e t : Qq7DmbMYxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Secvent ,a de cod 4.26: Configurare Microsoft Azure Active Directory
Detaliile de securitate pentru microservicii sunt specificate ˆın fis ,ierul Security-
Configuration din directorul config .ˆIn Spring Boot exist ˘a un mecanism de hooking , care
permite stabilirea unor reguli de acces la serviciul oferit de un endpoint, pe baza unor
expresii (vezi secvent ,a de cod 4.27).
1public c l a s s SecurityConfiguration extends ResourceServerConfigurerAdapter f
2 . . .
3 @Override
4 public void configure ( HttpSecurity http ) throws Exceptionf
5 http
6 . c s r f ( )
7 . . .
8 . and ( )
9 . authorizeRequests ( )
10 . antMatchers ( HttpMethod . POST , ”/api / ” ) . hasAuthority (
AuthoritiesConstants . EDITOR)
11 . . .
12 . antMatchers ( ”/management/health ” ) . permitAll ( ) ;
13g
14g
Secvent ,a de cod 4.27: Configurarea securit ˘at,ii pentru microserviciul Planning
ˆIn fis ,ierul serviceEndpoints.yml din directorul src/main/config sunt configurate
endpoint-urile pentru accesarea Azure Active Directory s ,i folosite mai departe ˆın clasa
client pentru Azure Graph API ( CustomAzureADGraphClient din pachetul com.virtu-
al7.planning.aad.filter ).
Grupurile care pot fi accesate de utilizator sunt transmise la server sub form ˘a
de GUID (Grup ID), iar ˆın fis ,ierul application-prod.yml sunt asociate nis ,te nume su-
gestive acestor ID-uri (vezi secvent ,a de cod 4.28). Cele 2 roluri permise ˆın aplicat ,ie
sunt PLANNING USER (utilizatorii cu acest rol pot doar s ˘a vizualizeze planific ˘arile
angajat ,ilor) s ,iPLANNING EDITOR (utilizatorii cu acest rol pot s ,i s˘a modifice plani-
fic˘arile angajat ,ilor).
44

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
1a p p l i c a t i o n :
2 azuregroups :
3o b j e c t I d : 2 b060e3e 372c467eb67ece23fexxxxxx
4 displayName : PLANNING USER
5o b j e c t I d : 45 dcf57c 08244123b8996c03d1xxxxxx
6 displayName : PLANNING EDITOR
Secvent ,a de cod 4.28: Rolurile utilizatorilor
Pentru profilul dev(development), nu a fost nevoie de un apel separat la Micro-
soft Azure ˆıntruc ˆat am folosit Keyclock (solut ,ie open source pentru gestionarea iden-
tit˘at,ii s ,i a accesului pentru aplicat ,ii), care implementeaz ˘a doar o extensie de OAuth
(face autentificarea, dar pe baza unor profiluri de utilizatori cu roluri prestabilite).
1s e c u r i t y :
2oauth2 :
3 c l i e n t :
4 accesstokenu r i : http : // l o c a l h o s t :9080/ auth/realms/ v i r t u a l 7 realm/
protocol/openid connect/token
5 userauthorization u r i : http : // l o c a l h o s t :9080/ auth/realms/ v i r t u a l 7
realm/protocol/openid connect/auth
6 c l i e n tid : v i r t u a l 7 a p p
7 c l i e n ts e c r e t : web app
8 scope : openid p r o f i l e email
9 resource :
10 userinfou r i : http : // l o c a l h o s t :9080/ auth/realms/ v i r t u a l 7 realm/
protocol/openid connect/ u s e r i n f o
Secvent ,a de cod 4.29: Configurare OAuth2 pentru profilul dev
ˆIn cazul comunic ˘arii inter-server, am atas ,at la header-ul cererii/r ˘aspunsului HTTP
REST s ,i idtoken. Mai multe detalii privind mecanismul de autorizare ˆın comunicarea
inter-server, sunt prezentate ˆın sect ,iunea 4.5.
45

CAPITOLUL 4. DETALII DE PROIECTARE S ,I IMPLEMENTARE
46

5 Operarea, testarea s ,i performant ,ele aplicat ,iei
5.1 Mecanismul de deployment
Microserviciile aplicat ,iei Planning sunt gestionate folosind Kubernetes s ,i depo-
zite ( containers ) Docker. Sunt utilizate 3 noduri de Kubernetes , din care ˆıntotdeauna
unul dintre ele este Master , iar celelalte doua sunt Slave . Fiecare nod ruleaz ˘a un c ˆate
unRancherOS (o distribut ,ie de Linux folosit ˘a pentru gestionarea containerelor Doc-
ker), ˆın care e rulat un POD (o grupare de unul sau mai multe containere – vezi figura
5.1). Pod-urile grupeaz ˘a imaginile containerului ˆıntr-o unitate detas ,abil˘a.
Figura 5.1: Diagrama de deployment [10]
ˆIn cazul aplicat ,iei Planning, ˆıntr-un container se afl ˘a un microserviciu (Gateway,
Employee sau Planning). Atunci c ˆand aplicat ,ia e pornit ˘a, microserviciile sunt rulate
ˆın cˆate un nod, iar ˆın funct ,ie de intensitatea cu care e utilizat un anumit microserviciu,
47

CAPITOLUL 5. OPERAREA, TESTAREA S ,I PERFORMANT ,ELE APLICAT ,IEI
Rancher-ul poate decide s ˘aˆılˆıncarce ˆınˆınc˘a un nod sau nu.
Folosind aceast ˘a metod ˘a de rulare a microserviciilor, aplicat ,iile pot fi localizate pe
aceleas ,i mas ,ini f˘ar˘a s˘a se influent ,eze reciproc [10], ceea ce asigur ˘a o mai mare eficient ,˘a
s,i, de asemenea, reduce costul hardware-ului, ˆıntruc ˆat sunt utilizate mai put ,ine mas ,ini,
deci scade totodat ˘a s,i costul arhitecturii bazate pe microservicii.
5.2 Testarea aplicat ,iei
Pentru a verifica modul ˆın care se comport ˘a aplicat ,ia, a fost necesar ˘a realizarea
de teste atat pe partea de backend, c ˆat s ,i pe partea de frontend. Tipul de testare abor-
dat este White-Box ,ˆın care testerul analizeaz ˘a structura intern ˘a a unei componente.
Platforma Java ofer ˘a o modalitate de testare White-Box a diverselor componente fo-
losind testarea unitar ˘a (Unit Tests ). Un avantaj al test ˘arii unitare este acela c ˘a pot fi
testate anumite funct ,ionalit ˘at,i imediat ce au fost implementate, f ˘ar˘a s˘a fie nevoie de o
interfat ,˘a pentru utilizator.
Pentru a scrie testele unitare pe partea de back-end am folosit Mockito s ,i Spring
Test Framework, iar testele se afl ˘aˆın pachetul com.virtual7.planning.web.rest din di-
rectorul src/test . Am scris c ˆate o clas ˘a de test (anotat ˘a cu @SpringBootTest) pentru
fiecare controler REST, iar metodele care testeaz ˘a sunt anotate cu @Test (vezi secvent ,a
de cod 5.1).
1@RunWith ( SpringRunner . c l a s s )
2@SpringBootTest ( c l a s s e s = PlanningApp . c l a s s )
3public c l a s s BupAssignedResourcesResourceIntTest f
4 . . .
5 @Test
6 @Transactional
7 public void getBupAssignedResources ( ) throws Exceptionf
8 // I n i t i a l i z e the database
9 bupAssignedResourcesRepository . saveAndFlush ( bupAssignedResources ) ;
10 // Get the bupAssignedResources
11 restBupAssignedResourcesMockMvc . perform ( get ( ”/api/bup assigned
resources /fidg” , bupAssignedResources . getId ( ) ) )
12 . andExpect ( s t a t u s ( ) . isOk ( ) )
13 . andExpect ( jsonPath ( ”$ . id ” ) . value ( bupAssignedResources . getId ( ) .
intValue ( ) ) ) ;
14g
15 . . .
16g
Secvent ,a de cod 5.1: Anotarea claselor de test
Pentru a scrie testele unitare de pe partea de frontend, am folosit Karma s,iJas-
mine . Jasmine este un framework de testare BDD (Behavior-Driven Development),
48

CAPITOLUL 5. OPERAREA, TESTAREA S ,I PERFORMANT ,ELE APLICAT ,IEI
care ofer ˘a un mediu de testare pentru javascript s ,i foloses ,te fis ,iere JSON pentru a si-
mula r ˘aspunsurile de la serviciile REST. Karma ruleaz ˘a teste JavaScript s ,i ofer ˘a suport
pentru Jasmine.
Testele Karma se afl ˘a pe Gateway ˆın directorul /src/main/webapp-ojet/src/test
/planning . Pentru a putea realiza aceste teste, am creat fis ,iere JSON corespunz ˘atoare
r˘aspunsurilor serviciilor folosite ˆın teste, ˆıntr-o ierarhie de pachete care s ˘a simuleze
URI-urile serviciilor (vezi figura 5.2).
Figura 5.2: Fis ,ierele necesare test ˘arii Karma
ˆIn fis ,ierul planningModelMock se instaleaz ˘a un Mock Server , care ˆıncarc ˘a fis ,ierele
JSON s ,i pune c ˆate un spion pe fiecare endpoint folosit ˆın teste, astfel ˆıncˆat atunci c ˆand
se acceseaz ˘a un endpoint, s ˘a trimit ˘a ca r ˘aspuns fis ,ierul JSON corespunz ˘ator. ˆIn fis ,ierul
planningModelSpec se afl ˘a testele propriu-zise. ˆIntˆai se apeleaz ˘a funct ,ia de instalare
a serverului mock, se apeleaz ˘a serviciile necesare s ,i se salveaz ˘a r˘aspunsurile lor ˆın
variabile (vezi secvent ,a de cod 5.2).
1// Functia beforeEach asigura ca va f i prima executata
2beforeEach ( function ( done ) f
3 // Setez timpul maxim de a s t e p t a r e a l r a s p u n s u r i l o r de l a server
4 originalTimeout = jasmine . DEFAULT TIMEOUT INTERVAL ;
5 jasmine . DEFAULT TIMEOUT INTERVAL = 10000;
6 // I n s t a l e z mock server s i salvez in v a r i a b i l e raspunsurile obtinute
din Promiseu r i
7 s e l f . planningModelMock = new PlanningModelMock ( ) ;
8 s e l f . planningModelMock
9 . installMockServer ( )
10 . then ( ( ) = >freturn SRV . getGridData ( 7 0 ) ; g)
11 . then ( ( data ) = >fs e l f . gridData = data ; g)
12 . then ( ( ) = >freturn SRV . getBusinessDays ( 7 0 ) ; g)
13 . then ( ( businessDays ) = >fs e l f . businessDays = businessDays ; g)
14 . then ( ( ) = >fdone ( ) ;g) ;g) ;
Secvent ,a de cod 5.2: Init ,ializarea datelor pentru testele Karma
49

CAPITOLUL 5. OPERAREA, TESTAREA S ,I PERFORMANT ,ELE APLICAT ,IEI
Astfel, pentru a testa, spre exemplu, c ˘a trimestrele dintr-un interval de timp s-au
generat corespunzator, creez obiectul UIPlanningDataGrid model (care cont ,ine modelul
gridului s ,i stocheaz ˘a trimestre, luni s ,i planific ˘ariˆın mod ierarhic ˆın vectorul quarters ),
apoi folosind metodele Jasmine expect() s,itoBe() , testez ca pe fiecare pozit ,ie a vecto-
rului am valoarea as ,teptat ˘a (vezi secvent ,a de cod 5.3).
1i t ( ’ Planning data qua rter s check ( time range : one year ) ’ , function ( done ) f
2 var uiPlanningDataGridModel = new UIPlanningDataGridModel ( s e l f .
gridData , s e l f . editType , s e l f . businessDays , ’ 2018 0101 ’ , ’ 20181231 ’ ) ;
3 expect ( uiPlanningDataGridModel . quar ters . length ) . toBe ( 5 ) ;
4 expect ( uiPlanningDataGridModel . quar ters [ 0 ] . months . length ) . toBe ( 3 ) ;
5 expect ( uiPlanningDataGridModel . quar ters [ 1 ] . months . length ) . toBe ( 3 ) ;
6 expect ( uiPlanningDataGridModel . quar ters [ 2 ] . months . length ) . toBe ( 3 ) ;
7 expect ( uiPlanningDataGridModel . quar ters [ 3 ] . months . length ) . toBe ( 3 ) ;
8 expect ( uiPlanningDataGridModel . quar ters [ 4 ] . months . length ) . toBe ( 1 ) ;
9g) ;
Secvent ,a de cod 5.3: Testarea gener ˘arii trimestrelor ˆıntr-un interval de timp dat
Pe lˆang˘a testarea unitar ˘a, pe partea de frontend am realizat s ,i testare end-to-end,
ˆın care am testat manual aplicat ,ia din interfat ,˘a s,i am observat cum se comport ˘aˆıntregul
sistem ˆın cazul unor scenarii reale de utilizare. Testarea end-to-end m-a ajutat cel mai
mult la descoperirea de erori at ˆat pe frontend, c ˆat s ,i pe backend.
5.3 Rezultate experimentale
Pentru a analiza performant ,a aplicat ,iei Planning, pe de-o parte am verificat anu-
mit ,i parametrii de performant ,˘a la runtime , iar pe de alt ˘a parte am cerut p ˘arerea per-
soanelor care deja au folosit aplicat ,iaˆın mod productiv.
5.3.1 Analiza performant,ei la runtime
Pentru aceast ˘a analiz ˘a am folosit Chrome Developer Tools s,i am ˆınregistrat valorile
parametrilor de performant ,˘aˆın timp ce am ˆınc˘arcat ˆın browser pagina de Overview
(deoarece aceasta necesit ˘a mai multe date de la server dec ˆat cea de Planning s ,i cont ,ine
s,i o cantitate mai mare de scripting).
Una dintre metricile folosite pentru a m ˘asura performant ,a unei animat ,ii este Fra-
mes Per Second (FPS), iar pentru ca utilizatorii aplicat ,iei s˘a fie mult ,umit ,i, FPS ar trebui
s˘a se afle ˆın jurul valorii 60. ˆIn partea de sus a figurii 5.3 este m ˘asurat ˘a aceast ˘a metric ˘a;
port ,iunile ros ,ii indic ˘a faptul c ˘a valoarea FPS a sc ˘azut foarte mult ˆıncˆat ar putea s ˘a de-
ranjeze utilizatorul, iar port ,iunile verzi indic ˘a o valoare foarte mare. ˆIn cazul nostru
performant ,a FPS e bun ˘a,ˆıntruc ˆat port ,iunile ros ,ii sunt mici s ,i rare.
Sub diagrama FPS se afl ˘a diagrama utiliz ˘arii Central Processing Unit (CPU), iar
culorile din aceast ˘a diagram ˘a corespund culorilor din diagrama figurii 5.4.
50

CAPITOLUL 5. OPERAREA, TESTAREA S ,I PERFORMANT ,ELE APLICAT ,IEI
Figura 5.3: Metricile de performant ,˘a laˆınc˘arcarea paginii Overview
Figura 5.4: Analiza utiliz ˘arii CPU
Din diagrame se observ ˘a faptul c ˘aˆınc˘arcarea fis ,ierelor javascript necesit ˘a cel mai
mult timp s ,i consum ˘a cel mai mult CPU, ˆıns˘a faptul c ˘aˆın timpul rand ˘arii (marcat ˘a pe
grafic cu culoarea violet) culoarea galben ˘a seˆıntinde p ˆan˘aˆın partea de sus a diagramei,
este un indiciu c ˘a CPU-ul a fost dep ˘as,it.
Pentru a g ˘asi cauza performant ,ei mai sc ˘azute la randare, am minimizat peri-
oada de timp analizat ˘a (vezi figura 5.5) s ,i am folosit sect ,iunea Main pentru a afis ,a
informat ,iileˆınregistrate ˆın intervalul de timp selectat.
Triunghiul ros ,u cu care sunt marcate anumite evenimente indic ˘a faptul c ˘a ar pu-
tea fi o problem ˘a cu evenimentele respective. ˆIn cazul acestei aplicat ,ii, ca posibil ˘a cauz ˘a
pentru performant ,a mai sc ˘azut ˘aˆın timpul rand ˘arii, este indicat fis ,ierul ojdatagrid.js
(implementat de framework-ul OJET) care necesit ˘a pˆan˘a la 45 ms pentru recalcularea
layout-ului pentru grid.
51

CAPITOLUL 5. OPERAREA, TESTAREA S ,I PERFORMANT ,ELE APLICAT ,IEI
Figura 5.5: Analiza cauzei utiliz ˘arii maxime a CPU-ului pe anumite port ,iuni
5.3.2 Analiza performant,ei pe baza opiniei utilizatorilor
Pentru a verifica faptul c ˘a obiectivele legate de performant ,˘a s ,i utilizabilitate au
fost atinse, am analizat aplicat ,ia s ,i pe baza opiniei utilizatorilor, avand ˆın vedere c ˘a
aceasta e lansat ˘a spre folosire de aproximativ 4 luni.
ˆIn acest scop am cerut unui grup de 10 persoane s ˘a atribuie un punctaj ˆıntre 1 s ,i
5 la 4 ˆıntreb ˘ari formulate de mine:
Cum at ,i nota aspectul aplicat ,iei ?
Cˆat de us ,or este de folosit aplicat ,ia ?
Cˆat de repede se realizeaz ˘a operat ,iile din cadrul aplicat ,iei ?
Cum at ,i nota experient ,a folosirii acestei aplicat ,ii, comparativ cu vechea aplicat ,ie
de planificare ?
Rezultatele sondajului de opinie sunt reprezentate ˆın graficele de mai jos.
Figura 5.6: R ˘aspunsuri la ˆıntrebarea 1.
Figura 5.7: R ˘aspunsuri la ˆıntrebarea 2.
52

CAPITOLUL 5. OPERAREA, TESTAREA S ,I PERFORMANT ,ELE APLICAT ,IEI
Figura 5.8: R ˘aspunsuri la ˆıntrebarea 3.
Figura 5.9: R ˘aspunsuri la ˆıntrebarea 4.
ˆIn ceea ce prives ,te aspectul aplicat ,iei, us ,urint ,aˆın utilizare s ,i rapiditatea cu care
aplicat ,ia realizeaz ˘a operat ,iile la care e supus ˘a, majoritatea persoanelor s-au declarat
mult ,umite, oferind nota 4 sau 5. Totodat ˘a se remarc ˘a faptul c ˘a pe baza opiniei utiliza-
torilor, atat aspectul, c ˆat s ,i timpul de execut ,ie al operat ,iilor ar putea fi ˆımbun ˘at˘at,ite. Pe
de alt ˘a parte, toate persoanele sunt foarte mult ,umite de aplicat ,ie per total s ,i o prefer ˘a
ˆın detrimentul celei vechi.
53

CAPITOLUL 5. OPERAREA, TESTAREA S ,I PERFORMANT ,ELE APLICAT ,IEI
54

6 Concluzii s ,i perspective
6.1 Concluzii
Aplicat ,ia Planning este o platform ˘a stabil ˘a pentru planificarea disponibilit ˘at,ii
angajat ,ilor, care este folosit ˘aˆın cadrul companiei Virtual7 de mai bine de 4 luni, pro-
ductiv s ,i f˘ar˘a probleme.
Obiectivele stabilite legate de performant ,˘a s,i utilizabilitate au fost atinse, ˆıntruc ˆat,
prin comparat ,ie cu vechea aplicat ,ie, Planning este us ,or de folosit s ,iˆınt ,eles s ,i pune la
dispozit ,ie un cod al culorilor care s ˘a ajute utilizatorul ˆın procesul de planificare sau
verificare a disponibilit ˘at,ii anumitor angajat ,i. De asemenea, paginile se ˆıncarc ˘a foarte
rapid, fapt care faciliteaz ˘a s,i navigarea de la o pagin ˘a la alta. Totodat ˘a, pe baza opiniei
utilizatorilor, aspectul aplicat ,iei s ,i timpul de execut ,ie al operat ,iilor pe care le realizeaz ˘a,
ar putea fi ˆımbun ˘at˘at,ite.
Datorit ˘a arhitecturii bazate pe microservicii, Planning poate fi us ,or integrat ˘a cu
celelalte viitoare aplicat ,ii interne ale companiei, iar structura modular ˘a s ,i bazat ˘a pe
nivele a microserviciilor permite ca aplicat ,ia s˘a fie extins ˘a cu us ,urint ,˘a.
6.2 Sinteza contribut ,iilor
Contribut ,iileˆın realizarea aplicat ,iei Planning sunt enumerate ˆın cele ce urmeaz ˘a:
Cercetarea ˆın vederea obt ,inerii ideilor legate de design-ul aplicat ,iei Planning client
s,i datele afis ,ateˆın pagini, astfel ˆıncˆat aceasta s ˘a fie mult mai us ,or de folosit prin
comparat ,ie cu vechea aplicat ,ie de planificare;
Implementarea unui algoritm folosit ˆın generarea gridurilor din pagina de Plan-
ning s ,i cea de Overview, al ˘aturi de componenta ojDataGrid pus ˘a la dispozit ,ie de
framework-ul Oracle JET ;
Implementarea funct ,iilor pentru preluarea, modificarea s ,i s,tergerea datelor de pe
servere ˆın mod eficient, folosind JS Promises (un Promise este rezultatul, de va-
loare sau es ,ec, al unei operat ,ii asincrone s ,i poate avea atas ,at˘a o funct ,ie de callback
ˆın care rezultatul poate fi prelucrat);
55

CAPITOLUL 6. CONCLUZII S ,I PERSPECTIVE
Popularea cu date a diferitelor componente din interfat ,a cu utilizatorul, ˆın mod
specific framework-ului Oracle JET;
Implementarea de scurt ˘aturi pentru tastatur ˘a (keyboard shortcuts ) care s ˘a faciliteze
utilizarea aplicat ,iei;
Implementarea unui mecanism de navigare ˆıntre planific ˘arile angajat ,ilor, inter-
vale de timp s ,i departamente folosind scurt ˘aturi de la tastatur ˘a sau butoane de
pe paginile corespunz ˘atoare ale aplicat ,iei;
Implementarea unui clase utilitare care eficentizeaz ˘a rutarea modulelor ˆın Oracle
JET s ,i care poate fi folosit ˘a foarte simplu de orice aplicat ,ie;
Refactorizarea s ,i adaugarea de noi tabele ˆın baza de date a aplicat ,iei vechi de
planificare, astfel ˆıncˆat aceasta s ˘a r˘aspund ˘a la cerint ,ele noii aplicat ,ii s ,i sa cresc ˘a
performant ,a cu care datele sunt preluate de la server;
Generarea aplicat ,iei pe partea de backend sub form ˘a de microservicii pentru a
putea fi integrat ˘aˆıntr-o arhitectur ˘a bazat ˘a pe microservicii;
Implementarea endpoint-urilor REST necesare popul ˘arii cu date a componente-
lor Oracle JET din aplicat ,ia client;
Deducerea num ˘arului de zile ˆın care un angajat e disponibil;
Calcularea efortului depus de angajat ˆın funct ,ie de eficient ,a acestuia;
Implementarea comunic ˘arii inter-server dintre microserviciile Employee s ,i Plan-
ning folosind Feign;
Integrarea aplicat ,iei cu mecanismele de securitate s ,i autentificare realizate pentru
intregul sistem de aplicat ,ii interne ale companiei;
Implementarea de teste unitare atat pe partea de frontend, c ˆat s ,i pe partea de
backend;
Realizarea analizei de performant ,˘a s,i utilizabilitate a aplicat ,iei.
ˆIn continuare ofer suport utilizatorilor ˆın cazul ˆın care descoper ˘a o problem ˘a, vin
cu noi sugestii de implementare sau au nevoie de ajutor.
56

CAPITOLUL 6. CONCLUZII S ,I PERSPECTIVE
6.3 Direct ,ii de continuare a dezvolt˘ arii
Pentru a ˆımbun ˘at˘at,i aplicat ,ia, pe viitor as ,putea s ˘aˆıi adaug mai multe funct ,ionali-
t˘at,i, astfel ˆıncˆat s˘a poat ˘a fi folosit ˘a s,i mai productiv de anumite categorii de utilizatori.
Spre exemplu, cum angajat ,ii de pe departamentul de v ˆanz˘ari pot vizualiza planific ˘arile
astfel ˆıncˆat s˘a s ,tie care dezvoltatori de software ar fi disponibili pentru proiectele vi-
itoare, as ,putea crea alte dou ˘a pagini ˆın aplicat ,ie care s ˘a permit ˘a celor de pe depar-
tamentul v ˆanz˘ari s ˘a gestioneze informat ,iile despre client ,i s,i proiecte pe baza plani-
fic˘arilor vizualizate. Cu ajutorul paginii Gestioneaz˘ a Proiecte , ar putea adauga noi pro-
iecte ˆın baza de date s ,i ar putea modifica asign ˘arile angajat ,ilor la diferite proiecte. ˆIn
mod similar, cu ajutorul paginii Gestioneaz˘ a Client ,i, ar putea adauga noi client ,iˆın baza
de date sau ar putea modifica datele despre proiectele asignate la anumit ,i client ,i.
57

CAPITOLUL 6. CONCLUZII S ,I PERSPECTIVE
58

Referint ,e bibliografice
[1] Martin L Abbott and Michael T Fisher. The art of scalability: Scalable web architec-
ture, processes, and organizations for the modern enterprise . Pearson Education, 2009,
pp. 12–63.
[2] Chris Richardson. Microservices patterns . Manning Publications, Shelter Island,
2019, pp. 3–41. ISBN : 9781617294549.
[3] Matt Raible. The JHipster mini-book . InfoQ, 2016, pp. 11–68, 139–150. ISBN : 978132
9638143.
[4] Oracle. Oracle JET . 2017. URL:https://docs.oracle.com/middleware/
jet320/jet/developer/GUID-293CB342-196F-4FC3-AE69-D1226A0-
25FBB.htm#JETDG113 . (accesat: 21.03.2019).
[5] Daniel Curtis. Practical Oracle JET . Springer, 2019, pp. 1–31. ISBN : 9781484243459.
[6] Craig Walls. Spring Boot in action . Manning Publications, 2016, pp. 1–88. ISBN :
9781617292545.
[7] Gary Mak. Spring MVC framework . Springer, 2008, pp. 24–79.
[8] Oracle. JSDoc 3.4.3 . 2019. URL:https://www.oracle.com/webfolder/
technetwork/jet/jsdocs/oj.Router.html . (accesat: 21.03.2019).
[9] Microsoft. Azure Active Directory Spring Boot Starter . 2019. URL:https://git-
hub . com / microsoft / azure – spring – boot / tree / master / azure –
spring-boot-starters/azure-active-directory-spring-boot-
starter . (accesat: 18.05.2019).
[10] The Kubernetes Authors. Kubernetes Documentation . 2019. URL:https://kuber-
netes.io/docs/home/ . (accesat: 16.05.2019).
59

ANEXA 1: GHIDUL UTILIZATORULUI
60

ANEXA 1: Ghidul utilizatorului
A. Autentificarea
Dup ˘a rularea Gateway -ului s ,i a microserviciilor Planning s ,i Employee, aplicat ,ia
poate fi accesat ˘a la URL-ul https://localhost:8000/gtw/index.html?root=planning .
ˆIn funct ,ie de modul ˆın care ruleaz ˘a aplicat ,ia (dev, prod, test), va aparea pagina
de logare ˆın care se introduc numele s ,i parola utilizatorului. ˆIn cazul de fat ,˘a Planning
ruleaz ˘aˆın modul development, as ,a c˘a se va deschide o pagina de logare Keycloak.
Figura .0.1: Pagina de autentificare din Keycloak
Aplicat ,ia este disponibil ˘a doar pentru utilizatorii care sunt s ,efi de departamente,
membrii ai Departamentului V ˆanz˘ari sau membrii ai Departamentului Resurse Umane.
B. Pagina Planning
Aceasta este pagina principal ˘a a aplicat ,iei,ˆın care angajat ,ii de pe departamentele
de dezvoltare software pot fi planificat ,i. La ap ˘asarea butonului Filter sau a combinat ,iei
de taste CTRL+ALT+F, se deschide canvasul ˆın care poate fi selectat departamentul,
angajatul s ,i perioada pentru care se face planificarea.
61

ANEXA 1: GHIDUL UTILIZATORULUI
Figura .0.2: Canvasul paginii Planning
Cˆampul Edit permite comutarea modului de editare a grilei cu date ˆıntre: edita-
rea duratei pentru care e planificat angajatul sau editarea eficient ,ei angajatului. Apa-
sarea butonului Generate sau a tastei ENTER, determin ˘a generarea gridului (figura
.0.3).
Figura .0.3: Grila cu date din pagina Planning ˆın modul de editare al duratei
ˆIn partea de sus a paginii este afis ,at numele angajatului selectat s ,i tipul s ˘au de
contract (cu norm ˘aˆıntreag ˘a sau part ,ial˘a).
Pe primul nivel din partea de header a grilei cu date se afl ˘a trimestrele cores-
62

ANEXA 1: GHIDUL UTILIZATORULUI
punz ˘atoare anului pentru care se face planificarea, pe nivelul al doilea se afl ˘a lunile
fiec˘arui trimestru pentru care sunt specificate s ,i zilele disponibile (de planificat) ale
angajatului ˆın luna respectiv ˘a, iar pe ultimul nivel se afl ˘a coloanele corespunz ˘atoare
celulelor ˆın care se editeaz ˘a durata planificat ˘a (D) s ,i se afis ,eaz˘a efortul depus de anga-
jat (E).
Culoarea lunilor indic ˘a num ˘arul de zile r ˘amase neplanificate pentru un anumit
angajat s ,i corespunde legendei din partea de sus a paginii.
Efortul este calculat ca s ,i produs ˆıntre durat ˘a, eficient ,˘a s ,i eficient ,˘a de baz ˘a (sto-
cat˘aˆın baza de date pentru fiecare angajat). Eficient ,a se stabiles ,teˆın funct ,ie de cat de
mult c ˘al˘atores ,te angajatul (dac ˘a acesta are 8 ore de c ˘al˘atorie pe sapt ˘amˆan˘a, eficient ,a
va sc ˘adea de la 1, adic ˘a 100% la 0.8, adic ˘a 80%) s ,iˆın funct ,ie de nivelul de cunos ,tint ,e
dobˆandit de angajat (dac ˘a angajatul este Junior, va avea eficient ,a mai mic ˘a dec ˆat un
Senior). Eficient ,a de baz ˘a se stabiles ,teˆın funct ,ie de c ˆate zile pe s ˘apt˘amˆan˘a lucreaz ˘a
angajatul (dac ˘a lucreaz ˘a de luni p ˆan˘a vineri, eficient ,a sa de baz ˘a va fi 1). Eficient ,a de
baz˘a este stocat ˘a pentru fiecare angajat ˆın baza de date, iar eficient ,a se poate edita din
pagina Planning (vezi figura .0.4).
Figura .0.4: Grila cu date din pagina Planning ˆın modul de editare al eficient ,ei
ˆIn ambele moduri de editare ale grilei, datele pot fi editate doar pe coloanele D,
respectiv A, prin selectarea celulei dorite. Valoarea pentru durat ˘a trebuie s ˘a fie un
num ˘ar mai mic sau egal cu 50, cu maxim o zecimal ˘a, iar valoarea pentru eficient ,˘a
trebuie s ˘a fie un num ˘ar mai mic sau egal cu 1, cu maxim 2 zecimale (figurile .0.5 s ,i
.0.6). Pot fi folosite s ˘aget ,ile tastaturii pentru a naviga ˆıntre celule. Dup ˘a ce celula a
fost editat ˘a, salvarea valorii se face prin ap ˘asarea tastei Enter. Ap ˘asarea tastei Tab,
63

ANEXA 1: GHIDUL UTILIZATORULUI
determin ˘a selectarea urm ˘atoarei celule editabile de pe r ˆandul curent, sau de pe r ˆandul
urm ˘ator dac ˘a nu mai exist ˘a celule editabile pe r ˆandul curent.
Figura .0.5: Popup cu mesaj de eroare pen-
tru valoare gres ,it˘a a duratei
Figura .0.6: Popup cu mesaj de eroare pen-
tru valoare gres ,it˘a a eficient ,ei
Prin ap ˘asarea s ˘aget ,ilor din dreptul numelui angajatului (sau prin folosirea combi-
nat ,iei de taste CTRL+S ˘AGEAT ˘A DREAPTA, respectiv CTRL+S ˘AGEAT ˘A ST ˆANGA), se
poate naviga printre angajat ,ii departamentului selectat ˆın canvas. Butoanele rotunde
de la baza grilei cu date permit navigarea ˆıntre intervalele de timp pentru care se afi-
seaz ˘a planificarea (navigheaz ˘a cu jum ˘atate de an ˆınainte, respectiv ˆınapoi).
Ultima coloan ˘a a grilei arat ˘a totalul de zile planificate pe un anumit proiect ˆın
intervalul de timp afis ,at. Ultimul r ˆand al grilei din modul de editare al duratei, reflect ˘a
num ˘arul de zile r ˘amase neplanificate, ˆın cazul ˆın care num ˘arul e pozitiv s ,i num ˘arul de
zile planificate ˆın plus, dac ˘a num ˘arul e negativ. Aceste valori se reg ˘asesc ˆın grila cu
date a paginii Overview (vezi ultimul r ˆand al grilei din figura .0.3, ˆın comparat ,ie cu
rˆandul corespunz ˘ator angajatului din figura .0.7).
C. Pagina Overview
Grila cu date a acestei pagini prezint ˘anum ˘arul de zile r ˘amase neplanificate ˆın
fiecare lun ˘a, pentru angajat ,ii unui departament. Celulele grilei sunt colorate pentru ca
utilizatorul s ˘a observe imediat pe baza codului culorilor explicat ˆın legenda din partea
de sus a paginii, care angajat ,i s,iˆın ce luni sunt neplanificat ,i sau prea mult planificat ,i.
ˆIn cazul ˆın care celula este goal ˘a s ,i de culoare verde ˆınchis, ˆınseamn ˘a c˘a angajatului
i-au fost planificate toate zilele disponibile.
Penultimul r ˆand al grilei afis ,eaz˘a num ˘arul total de zile r ˘amase neplanificate dintr-
un trimestru (pentru lunile afis ,ate din trimestrul respectiv) ˆın departamentul selectat.
Ultimul r ˆand al grilei afis ,eaz˘a num ˘arul total de zile planificate pentru tot ,i angajat ,ii de-
partamentului, ˆın fiecare trimestru. ˆIn figura .0.7, se observ ˘a c˘a ultimele 3 coloane sunt
ros ,ii, deci angajat ,ii au r ˘amas cu mai mult de 10 zile neplanificate ˆın lunile ianuarie, fe-
bruarie s ,i martie, ale anului 2018, iar celula goal ˘a de pe ultimul r ˆand, corespunz ˘atoare
64

ANEXA 1: GHIDUL UTILIZATORULUI
trimestrului 1 din anul 2018, indic ˘a faptul c ˘a pentru lunile respective, angajat ,ii depar-
tamentului nu au fost planificat ,i deloc.
Figura .0.7: Grila cu date din pagina Overview
Celulele acestei grile nu sunt editabile, ˆın schimb, dac ˘a se da click pe una dintre
celulele coloanei cu angajat ,i, utilizatorul va fi direct ,ionat automat spre pagina Plan-
ning corespunz ˘atoare angajatului selectat, iar intervalul de timp pentru care se afis ,eaz˘a
planific ˘arile este acelas ,i cu intervalul de timp ales ˆın pagina Overview.
Prin ap ˘asarea s ˘aget ,ilor din dreptul numelui departamentului (sau prin folosirea
combinat ,iei de taste CTRL+S ˘AGEAT ˘A DREAPTA, respectiv CTRL+S ˘AGEAT ˘A ST ˆAN-
GA), se poate naviga printre departamentele de dezvoltare software ale companiei
pentru a vizualiza num ˘arul de zile r ˘amase neplanificate. Butoanele rotunde de la mij-
locul grilei cu date permit navigarea ˆıntre intervalele de timp pentru care se afiseaz ˘a
num ˘arul de zile planificate (navigheaz ˘a cu un an ˆınainte, respectiv ˆınapoi).
De asemenea, ap ˘asarea butonului Filter sau a combinat ,iei de taste CTRL+ALT+F,
determin ˘a deschiderea canvasului din partea st ˆang˘a a paginii, fi selectat departamen-
tul pentru care se afis ,eaz˘a num ˘arul de zile r ˘amase neplanificate, s ,i datele de ˆınceput,
respectiv de sf ˆars ,it a intervalului de timp pentru care se afis ,eaz˘a grila. Canvasul este
ilustrat ˆın figura .0.8). Ap ˘asarea butonului Generate din canvas sau a tastei Enter, de-
termin ˘a generarea grilei cu date ˆın funct ,ie de valorile selectate ˆın canvas.
65

ANEXA 1: GHIDUL UTILIZATORULUI
Figura .0.8: Canvasul paginii Overview
D. Navigarea ˆ ıntre paginile aplicat ,iei
Dup ˘a cum am ment ,ionat anterior, din pagina Overview, prin selectarea unui an-
gajat din grila cu date, utilizatorul va fi direct ,ionat automat ˆın pagina Planning cores-
punz ˘atoare angajatului selectat s ,i care afis ,eaz˘a planific ˘arile pentru intervalul de timp
selectat ˆın pagina Overview. Ap ˘asarea butonului Back , trimite utilizatorul pe pagina
Overview anterioar ˘a. Acest mecanism de redirect ,ionare a paginilor faciliteaz ˘a proce-
sul planific ˘ariiˆıntruc ˆat utilizatorul vizualizeaz ˘aˆın pagina Overview angajat ,ii cu prea
putine zile planificate, apoi imediat poate ajunge pe pagina angajatului respectiv s ,iˆıl
poate planifica.
ˆIn cazul ambelor pagini, pot fi modificat ,i parametrii din URL s ,i dup ˘a ap ˘asarea
tastei Enter va fi regenerat ˘a grila cu date corespunz ˘ator modific ˘arilor efectuate ˆın URL.
Parametrii din URL corespund valorilor selectate ˆın canvasul paginii.
Figura .0.9: URL-ul paginii Planning
De exemplu, ˆın figura .0.9, se observ ˘a c˘a poate fi modificat id-ul angajatului (dac ˘a
utilizatorul ˆıl cunoas ,te), data de ˆınceput s ,i sfˆars ,it a perioadei pentru care se afis ,eaz˘a
planific ˘arile, precum s ,i modul de editare al grilei cu date (duration sau efficiency).
Totodat ˘a folosind aceste URL-uri, paginile pot fi marcate sau trimise sub form ˘a de link
altor persoane.
66

Similar Posts