Sistem de Evidenta Automata a Timpului Folosind Tehnologia Ibeacondocx
=== Sistem de evidenta automata a timpului folosind tehnologia iBeacon ===
UNIVERSITATEA TEHNICĂ „Gheorghe Asachi” din IAȘI
FACULTATEA DE AUTOMATICĂ ȘI CALCULATOARE
DOMENIUL : Calculatoare și Tehnologia informației
SPECIALIZAREA: Tehnologia Informației
Sistem de evidență automată
a timpului folosind
tehnologia iBeacon
LUCRARE DE LICENȚĂ
Coordonator științific
Conf. dr. ing. Mihai Horia Zaharia
Absolvent
Raileanu Ion
IAȘI 2015
DECLARAȚIE DE ASUMARE A AUTENTICITĂȚII
LUCRĂRII DE LICENȚĂ
Subsemnatul _______________________________________________________, legitimat(ă) cu __________ seria ____ nr. _________, CNP__________________ autorul(ea) lucrării __________________________________________________ ____________________________________________________________________________________________________________________________________ elaborată în vederea susținerii examenului de finalizare a studiilor de licență organizat de către Facultatea de Automatică și Calculatoare din cadrul Universității Tehnice „Gheorghe Asachi” din Iași, sesiunea a anului universitar, luând în considerare conținutul Art. 34 din Codul de etică universitară al Universității Tehnice „Gheorghe Asachi” din Iași (Manualul Procedurilor, UTI.POM.02 – Funcționarea Comisiei de etică universitară), declar pe proprie răspundere, că ceastă lucrare este rezultatul propriei activități intelectuale, nu conține porțiuni plagiate, iar sursele bibliografice au fost folosite cu respectarea legislației române (legea 8/1996) și a convențiilor internaționale privind drepturile de autor.
Data Semnătura
_______________ _______________________
Introducere
Motivație
Tehnologia Informației este domeniul care folosind calculatoare și alte echipamente de telecomunicație păstrează, regăsește, transmite și prelucrează date în contextul unui proces de afaceri. Harold J. Leavitt și Thomas L. Whisler au introdus acest termen în 1958, comentând că „noua tehnologie încă nu are un nume bine stabilit. O vom numi Tehnologia Informației”. Definiția lor consta din trei categorii: tehnici pentru procesarea datelor, aplicarea metodelor statistice și matematice în luarea deciziilor și simularea gândirii de nivel superior prin programe de calculator.
În prezent, termenul de Tehnologia Informației (TI) se referă la un șir de industrii cum ar fi cea a componentelor software și hardware, a electronicii și semiconductorilor, a dispozitivelor mobile și a echipamentelor de comunicație, a internetului și a comerțului electronic.
Într-un timp scurt, de circa jumătate de secol, de pe urma TI au beneficiat enorm domenii precum educația, medicina, cercetarea științifică, procesele tehnologice sau domeniul apărării. La ora actuală realizările Tehnologiei Informației au trecut la nivelul de a influența și modela comportamentul social al oamenilor.
Tradițional, acest domeniu a avut un ritm exponențial de dezvoltare, în fiecare an comunitatea științifică împreună cu companiile din domeniu au introdus pe piață noi tehnologii integrate în produse inovatoare, dintre care unele au cucerit rapid piața dar și atenția consumatorilor. În acest moment principiile după care se ghidează furnizorii dar și consumatorii de produse IT sunt următoarele:
Renunțarea treptată la sistemele de tip Desktop și Laptop și migrarea spre dispozitive cu interfață tactilă precum tablete dar mai ales telefoane inteligente (eng. smartphone);
Migrarea aplicațiilor de tip Desktop spre aplicații web sau aplicații pentru telefoane inteligente;
Renunțarea la stocarea și procesarea locală în favoarea serviciilor de cloud-computing;
Popularizarea arhitecturii orientate pe servicii;
Renunțarea la metodele clasice de monetizare a aplicațiilor software prin vânzarea de licențe în favoarea unor abonamente pe anumite perioade de timp;
Utilizarea pe o scară tot mai largă a telefoanelor inteligente pentru activitățile de zi cu zi, împreună cu o gamă largă de accesorii purtabile precum
ceasuri(Android Wear™, Apple Watch™), brățări inteligente (MOOV™), ochelari (vezi Google Glass™) dar și alte dispozitive care interconectate formează conceptul de Internet of Things;
Acordarea unei atenții tot mai mari dispozitivelor de realitate augmentată (vezi Oculus Rift™, Microsoft HoloLens™);
Ghidarea după aceste principii asigură unei companii sau unui dezvoltator individual al unui produs să intre pe piață și de cele mai multe ori să își recupereze și investițiile făcute pentru dezvoltarea produsului. Ingeniozitatea, gradul de inovare, design-ul, performanțele și prețul unui produs sau serviciu sunt factorii care fac diferența între produsele care vor dicta tendințele pieței și produsele care doar vor încerca să țină pasul și să supraviețuiască pe o piață a cărei competitivitate crește continuu.
Sistem de evidență automată al timpului folosind tehnologia iBeacon
Timpul este o resursă limitată iar gestiunea eficientă a sa este o componentă cheie care afectează în mod direct performanța activităților desfășurate de o organizație. În prezent, datorită constrângerilor economice, creșterii competitivității dar și a unor factori interni, majoritatea organizațiilor private dar și unele entități guvernamentale își plătesc angajații în dependență de numărul de ore efectiv lucrate. Această practică a condus la necesitatea instalării unor sisteme mai mult sau mai puțin performante care să monitorizeze timpul când angajații vin și pleacă de la serviciu. Majoritatea acestor sisteme funcționează pe baza unor cartele magnetice, care sunt scanate de angajați la intrarea în sediul organizației. Principalul lor avantaj este că realizează și restricționarea accesului, permițând accesul în clădire doar persoanelor care dețin o cartelă validă.
La capitolul dezavantaje, putem menționa că o cartelă poate fi pierdută, caz în care este necesară parcurgerea unui șir de proceduri birocratice pentru înlocuirea ei, sau uitată în diverse locuri, caz în care poți intra în clădire folosind cartela unui coleg sau o cartelă generică. În ambele cazuri, care sunt destul de comune, sistemul de evidență a timpului eșuează în a furniza rezultate relevante. Un alt dezavantaj care merită menționat este formarea cozilor la intrare, la orele de vârf, în cazul organizațiilor care au un număr mare de angajați.
O altă practică larg răspândită în cadrul multor companii este necesitatea completării manuale de către angajați a unor foi de pontaj, sau introducerea manuală și independentă a datelor în cadrul unui sistem informatic. Pe lângă efortul de centralizare al datelor în cazul primei situații, totalurile lunare vor fi mereu afectate de subiectivitatea angajaților atunci când raportează orele lucrate. De asemenea, orele de intrare și de ieșire din sediul organizației nu pot fi folosite pentru aprecierea corectă a timpului efectiv lucrat.
Problemele enumerate mai sus, legate de evidența timpului petrecut la serviciu de către angajați, pot fi rezolvate folosind un sistem automat bazat pe ultimele tehnologiile informatice disponibile la moment. Scopul acestui sistem este să ofere informații relevante și precise, fiind în același timp ușor de instalat și configurat, ușor de utilizat și mai ieftin decât soluțiile existente.
Soluția propusă este utilizarea tehnologiei iBeacon. Sistemul va fi compus dintr-o aplicație instalată pe telefonul mobil al angajatului, o aplicație web pentru configurarea sistemului, gestiunea angajaților monitorizați precum și generarea rapoartelor, disponibilă companiei și cel puțin un beacon instalat în incinta sediului companiei. Aplicația instalată pe telefonul angajatului v-a căuta periodic semnalul emis de către beacon. Detectarea semnalului se traduce prin faptul că angajatul respectiv se află în proximitatea acelui beacon, deci la locul său de muncă. Aplicația de pe telefon v-a trimite o înregistrare către server cu data, ora și locația angajatului în cadrul clădirii. Dacă telefonul nu este conectat la o rețea de date, înregistrarea va fi stocată local, urmând a fi trimisă atunci când este posibil schimbul de date între aplicație și server. Serverul aplicației v-a calcula pentru fiecare angajat timpul petrecut la serviciu, în fiecare locație a clădirii. Prin intermediul aplicației de configurare, managerul companiei sau al departamentului
v-a putea consulta orele de lucru ale fiecărui angajat și va putea genera rapoarte care pot fi folosite de către departamentul de contabilitate, atunci când se calculează salariile.
Angajatul trebuie doar să-și descarce aplicația pe telefon dintr-o sursă autorizată, să o înregistreze folosind codul unic furnizat de compania la care lucrează și să o lase să se execute în fundal.
Detalii despre avantaje, tehnologiile folosite, costuri sau impact asupra bateriei telefonului mobil vor fi tratate detailat în capitolul următor.
Așa cum este proiectat, sistemul poate fi adaptat să funcționeze și în alte scenarii de utilizare, cum ar fi atunci când este necesară o soluție scalabilă pentru evidența exactă a timpului de intrare sau ieșire dintr-o anumită locație cu investiții minime în echipamente. Voi prezenta astfel de scenarii în capitolele ce urmează.
Privire de ansamblu asupra tehnologiilor folosite
Telefoane inteligente
Un telefon inteligent ( eng. smartphone ) este un telefon mobil care dispune de un sistem de operare avansat. În mod obișnuit, un telefon inteligent combină funcționalitatea unui telefon mobil cu funcționalitatea mai multor dispozitive digitale precum cea a unui player multimedia, a unui navigator GPS, a unui asistent digital personal (eng. personal digital assistant ), a unei camere foto și video. În prezent majoritatea absolută a telefoanelor inteligente dispun de un ecran tactil de înaltă rezoluție, un set de senzori, conexiuni fără fir (Bluetooth, Wi-Fi, NFC, port infraroșu), conexiuni de date de mare viteză (UMTS, LTE) cât și conexiuni prin fir (port audio de 3.5mm, port USB).
Sistemul de operare este principala componentă a unui telefon inteligent. Datorită lui, s-a permis scrierea într-un timp scurt a unui număr imens de aplicații terțe care au condus la valorificarea eficientă a dotărilor hardware. În prezent există trei sisteme majore de operare adresate telefoanelor inteligente: Android (dezvoltat de Google), iOS (dezvoltat de Apple) și Windows Phone (dezvoltat de Microsoft).
Piața de telefoane inteligente a început să se dezvolte într-un ritm accelerat începând cu anul 2007 , atunci când a fost anunțat, iar mai apoi pus în vânzare primul model de iPhone – numele comercial al telefoanelor inteligente produse de către compania Apple.
În fiecare an, dotările telefoanelor inteligente s-au îmbunătățit, iar odată cu creșterea concurenței, din partea producătorilor chinezi, prețul lor a scăzut. În anul 2014, s-au vândut 1.3 miliarde de dispozitive, ceea ce înseamnă o creștere cu 27,7 % față de 2013, conform IDC. Conform Gartner , numărul de telefoane inteligente vândute l-a depășit pe cel al telefoanelor mobile încă din 2013, având o cotă de piață de 53.6%, iar tendința se menține. În Figura 2-1 este ilustrată cota fiecărui sistem de operare, până în anul 2014.
Figura 2-1 Cota sistemelor de operare pentru telefoane inteligente vândute până în 2014
După cum se observă sistemul de operare dezvoltat de Google, Android-ul domină piața telefoanelor inteligente , cu o cotă de piață de aproximativ 75%. Este urmat de iOS, cu o cotă care a crescut în ultimul an până la aproximativ 20%. Sistemul de operare produs de Microsoft a avut o evoluție stabilă în ultimii ani, având o cotă de aproximativ 4%. Putem afirma cu certitudine că în prezent unul din două telefoane este telefon inteligent, iar referitor la telefoanele inteligente, trei din patru telefoane rulează sistemul de operare Android.
Sistemul produs de Google este cel mai răspândit, însă totodată și cel mai fragmentat. În tabelul Tabel 2-1, este reprezentată distribuția versiunilor de Android conform Google.
Tabel 2-1 Distribuția versiunilor de Android
De notat că există diferențe software majore între versiunile de Android, dar și diferențe majore între API-urile furnizate pentru dezvoltarea de aplicații.
Tabelul Tabel 2-1 este foarte important atunci când vrem să dezvoltăm o aplicație adresată platformei Android, deoarece pe baza specificațiilor aplicației, ne dă o estimare a numărului de utilizatori care au dispozitive compatibile. De asemenea, spre deosebire de sistemele concurente, telefoanele care rulează Android sunt rareori actualizate la versiunea următoare. Trebuie de ținut cont și de acest aspect în procesul de proiectare a unei aplicații.
Conform graficului din Figura 2-1, sistemul de operare cu cota de piață cea mai mare este Android, acest lucru constituind unul din avantajele pentru care l-am ales ca platformă pentru dezvoltarea aplicației-client din cadrul sistemului automat de evidență al timpului.
Tehnologia Bluetooth Smart
Bluetooth este un standard de comunicație fără fir pe distanțe scurte, folosind frecvențe radio în banda de 2.4 GHz. A fost creat de către compania Ericsson, în anul 1994, ca o alternativă a standard-ului de comunicație serială prin cablu RS-232. Utilizarea comercială a acestui standard de comunicație începe în anul 2000, atunci când este pus în vânzare primul telefon mobil care suportă acest protocol de comunicație, prima placă PC, dar și primele căști fără fir care redau sunetul transferat către ele prin acest protocol. În următorii ani, adaptoare Bluetooth au fost integrate în aproape orice dispozitiv electronic, inclusiv mouse-uri, tastaturi, televizoare, laptop-uri, etc. Câte un adaptor Bluetooth se găsește practic în fiecare SoC (eng. System on a Chip) care este componenta de bază a unei game variate de echipamente electronice inteligente. La ora actuală se vând anual 2.5 miliarde de dispozitive cu Bluetooth, protocolul fiind prezent pe 90% din telefoanele mobile din lume.
De la apariție și până în prezent, standardul a fost îmbunătățit constant, reviziile majore având îmbunătățiri la capitolul putere consumată, rată de transfer a datelor și distanța de funcționare.
Odată cu popularizarea conceptului de Internet of Things și conectarea la rețea a unui număr tot mai mare de dispozitive, unele din ele cu o putere mare de procesare, dar mai ales cu o autonomie de funcționare limitată, s-a creat necesitatea dezvoltării unui standard de comunicație fără fir cu un impact redus sau chiar neglijabil asupra duratei de viață a bateriei.
În anul 2010, a fost definit standard-ul Bluetooth 4.0, numit și Bluetooth Smart, sau Bluetooth LE (Low Energy). Principala diferență față de versiunile anterioare era consumul neglijabil de energie, cu menținerea aceleiași distanțe de funcționare ( aproximativ 100m, în dependență de puterea emisă ). Acest nou tip de comunicație fără fir se adresa unei noi generații de aplicații în medicină, fitness, beacon-uri sau divertisment.
Conform specificațiilor, puterea consumată variază între 0.01W și 0.5W față de versiunea clasică a protocolului, iar curentul nu depășește 15mAh față de 30mAh în versiunea clasică. Conform unui studiu al companiei Aislelabs, un beacon cu o baterie de 1000mAh poate funcționa neîncetat timp de 1-2 ani. Pentru comparație, la un telefon care utilizează versiunea clasică a protocolului, aceeași bateria se consumă în câteva ore. Pentru scenarii reale de aplicații, impactul Bluetooth Smart asupra bateriei dispozitivului este neglijabil.
Beacon
Un beacon este un dispozitiv fizic care folosește un transmițător Bluetooth Low Energy pentru a trimite notificări despre locație dispozitivelor compatibile din apropiere. Numele său derivă de la iBeacon™ – o tehnologie pentru poziționarea în interior, introdusă de Apple în anul 2013 odată cu lansarea iOS 7. Tehnologia permite declanșarea unor acțiuni pe telefonul sau dispozitivul care se află în raza de acțiune a unui asemenea dispozitiv.
Din punct de vedere hardware, un beacon este un sistem, conținând un SoC bazat pe arhitectura ARM (vezi Figura 2-2, Figura 2-3 ), împreună cu un modul Bluetooth Smart, o antenă și o baterie. În dependență de producător, aceste dispozitive pot să mai conțină un senzor de temperatură sau un accelerometru. Întregul modul hardware este împachetat într-o carcasă din material plastic sau silicon (vezi Figura 2-2 și Figura 2-3 ), care după caz este impermeabilă, ceea ce înseamnă că beacon-ul poate fi folosit și în exteriorul unei clădiri.
Figura 2-2 Beacon produs de către compania Estimote
Beacon-ul emite la intervale regulate (de la 50 la 10000 de milisecunde) un pachet de date de până la 47 de octeți (vezi Figura 2-3).
Figura 2-3 Conținutul pachetului de date emis de un beacon conform cu specificațiile protocolului Bluetooth Low Energy
Primul octet din pachet reprezintă un preambul, următorii 4 octeți reprezintă adresa de acces, care pentru beacon-uri este tot timpul 0x8E89BED6, următorii maxim 39 de octeți reprezintă încărcătura utilă de date a pachetului, iar ultimii 3 octeți conțin un CRC prin care se verifică integritatea pachetului. Câmpul Header conține informații specifice despre lungimea, dar și interpretarea câmpului de date, iar câmpul MAC Address conține adresa MAC a beacon-ului. Semnificația octeților din încărcătura utilă de date a pachetului este redată în Figura 2-4.
Figura 2-4 Semnificația octeților din câmpul de date al pachetului emis de un beacon
Primii 9 octeți reprezintă prefixul protocolului iBeacon, acesta fiind o constantă fixată de către compania Apple. Următorii 16 octeți reprezintă un identificator unic (UUID) al producătorului beacon-ului, acest număr poate fi schimbat, transformându-se în identificatorul unic al beacon-ului. Câmpurile Major și Minor conțin 2 numere întregi pe 16 biți care la fel, pot fi schimbate, și care se recomandă a fi folosite pentru a identifica în mod unic un beacon din cadrul unui grup, instalat la aceeași locație. Ultimul câmp reprezintă complementul față de doi al puterii semnalului beacon-ului măsurat la distanța de 1 metru. Este o constantă fixată de producător, și care este folosită la calcularea distanței până la beacon.
Tehnologia beacon-urilor a fost gândită inițial pentru o nouă generație de aplicații pentru platforme mobile care să aducă utilizatorului informații despre ofertele comerciale din apropierea sa. O aplicație instalată pe un dispozitiv compatibil va scana continuu după semnalul emis de un beacon și va primi o notificare , sub forma unui triplet compus dintr-un număr unic de identificare pe 128 biți (UUID) și 2 numere pe 16 biți numite Major și Minor (vezi Figura 2-4). Această combinație trebuie să identifice în mod unic o locație și este trimisă de aplicație la un server care întoarce o ofertă comercială sau după caz, o informație relevantă pentru locația respectivă. Avantajul este precizia mare a localizării în interior, un metru sau chiar mai puțin, în dependență de calibrarea beacon-ului și de existența sau lipsa interferențelor electromagnetice. Alte metode de localizare(GPS, triangularizare semnal GSM sau Wi-Fi) au o precizie redusă în interiorul unei clădiri.
Distanța până la care funcționează tehnologia beacon-urilor variază de la câțiva centimetri până la peste 70 de metri, dar este influențată de condițiile mediului.
Prețul unui asemenea dispozitiv variază între 5 și 30$, și la moment există peste 15 producători de beacon-uri.
Un aspect important în cadrul acestei tehnologii este durata de viață a bateriei beacon-ului, care variază între o lună și doi ani. Ea este influențată de doi parametri: distanța de emisie și intervalul de emisie. O distanță de emisie mai mare înseamnă o putere consumată mai mare și implicit un consum mai rapid al bateriei.
De al doilea parametru depind performanțele cât și consumul de energie al aplicațiilor care folosesc informații contextuale obținute pe baza beacon-urilor. Astfel, setarea unui interval de emisie mic permite setarea unui timp de scanare mic în cadrul aplicației, deci un consum cât mai mic de energie. De exemplu, la un interval de emisie de 100 ms, un beacon va emite informații de 10 ori pe secundă. Scanarea timp de o secundă va descoperi beacon-ul cu o probabilitate extrem de mare. Pe de altă parte, setarea unui interval de emisie mare, (900 ms de exemplu), va conduce la o probabilitate redusă de descoperire a beacon-ului într-un timp de scanare de o secundă. Prin urmare, fie se v-a mări timpul de scanare, ceea ce va duce la un consum mai mare al bateriei dispozitivului, fie se v-a micșora timpul de emisie al beacon-ului. Alegerea unor setări optime se va face pe teren, după finalizarea dezvoltării aplicației și monitorizarea consumului de energie.
Figura 2-5 Beacon produs de către compania Kontakt
Trecând peste aspectele legate de partea hardware, investiție inițială și costuri de operare, un alt aspect de care trebuie să ținem cont atunci când vrem să dezvoltăm o aplicație bazată pe beacon-uri este suportul oferit de sistemul de operare țintă. Astfel cele mai utilizate sisteme de operare pentru dispozitive mobile (Google Android, Apple iOS, Microsoft Windows Phone) oferă suport pentru dispozitive Bluetooth Low Energy, în speță, beacon-uri. Dezavantajul este că fiecare o face după principii diferite, ceea ce face dificilă dezvoltarea unei aplicații multi-platformă cu aceeași arhitectură. Un alt dezavantaj este suportul Bluetooth Smart doar pentru ultimele versiuni ale sistemelor de operare. Astfel, Android suportă scanarea beacon-urilor începând cu versiunea 4.3 (Jelly Bean, API v.18), iOS începând cu iOS 7, iar Windows Phone începând cu versiunea 8.1. Acest dezavantaj este aproape insesizabil pentru ecosistemul iOS deoarece majoritatea absolută a dispozitivelor au deja una din versiunile suportate, însă în cazul Android, poate fi o problemă, din cauza fragmentării mari a platformei.
Tehnologia beacon-urilor este abia la început, majoritatea aplicațiilor care există în prezent se rezumă la descoperirea și afișarea de informații despre beacon-urile din apropiere. De asemenea, alegerea numărul unu a dezvoltatorilor este platforma iOS, deoarece acolo există un suport mai bun pentru aplicații Bluetooth Smart ceea ce conduce și la o eficiență energetică mai mare. Având în vedere existența unui număr mare de start-up – uri care dezvoltă aplicații în acest domeniu, un număr mare de producători de beacon-uri, dar și implicarea unor companii mari precum Google sau Apple, cred că tehnologia are potențial și va continua să se dezvolte în ritmuri susținute și în viitor.
Mobile Backend as a Service
Un mobile back end as a service (MBaaS) este un nou tip de serviciu bazat pe cloud computing apărut relativ recent, majoritatea furnizorilor acestui serviciu începându-și activitatea după 2011.
Ideea care stă în spatele acestui serviciu este că aplicațiile pentru telefoane inteligente necesită un șir de servicii care pot fi reutilizate de mai multe aplicații în loc să fie dezvoltate pentru fiecare aplicație în parte. Aplicațiile care folosesc un MBaaS au o arhitectură distribuită slab cuplată.
Serviciile oferite de un MBaaS variază de la un furnizor la altul, dar de obicei constau în notificări push, stocare și partajare de fișiere, integrare cu rețele sociale precum Facebook, Twitter, Google, servicii de localizare, funcții de chat și mesagerie, gestionarea utilizatorilor, posibilitatea de a rula scripturi și instrumente de analiză a datelor.
Un MBaaS nu este izolat față de ecosistemul aplicației care îl folosește și prin urmare pune la dispoziția programatorilor un set de apeluri REST dar și librării native pentru cele mai utilizate sisteme de operare pentru platforme mobile, cât și pentru limbajul Javascript.
În plus față de aceste facilități, backend-ul unei aplicații trebuie particularizat și programat pentru a răspunde la cerințele specifice. Prin urmare furnizorii de MBaaS oferă o combinație online și offline de medii de dezvoltare. Exemplu de mediu de dezvoltare online este interfața pentru definirea structurii bazei de date, iar ca mediu off-line este oferit un editor de cod Javascript particularizat pentru anumite operații specifice furnizorului respectiv.
În final, sistemele MBaaS operează continuu, prin urmare au nevoie de un mecanism de monitorizare al aplicațiilor și de înregistrare a erorilor. Aceste funcționalități sunt furnizate fie direct, fie prin intermediul unui alt serviciu.
Ca mediu de stocare al datelor și fișierelor, majoritatea furnizorilor de MBaaS folosesc sistemul de baze de date MongoDB, care este o bază de date NOSQL în regim open source și care stochează obiecte în format JSON.
La fel ca și la restul serviciilor oferite în cloud, prețul pentru utilizarea MBaaS se stabilește în dependență de cantitatea de servicii consumată. Trei factori importanți la stabilirea prețului sunt cantitatea de date stocate (de obicei se face diferență între cantitatea de date stocată sub formă de fișiere și cea stocată sub forma unor tabele de obiecte), numărul de cereri pe secundă ale aplicației la serviciile MBaaS și timpul de rulare al codului pe serverele din cadrul MBaaS. Taxarea începe odată cu depășirea unor anumite limite până la care serviciile sunt oferite în regim gratuit. Această limită variază de la un producător la altul.
Caracteristicile enumerate mai sus sunt comune tuturor furnizorilor de servicii de tip MBaaS. În plus față de aceste caracteristici, furnizorii din categoria enterprise oferă o integrare foarte bună cu aplicațiile și sistemele de stocare al datelor deja existente, securitate îmbunătățită, contracte de tip SLA (Service-level agreement).
Avantajele utilizării serviciilor unui furnizor de MBaaS sunt importante și sunt legate mai ales de aspectul financiar al dezvoltării unei aplicații. Folosirea acestor servicii elimină din start necesitatea investițiilor în infrastructură, sisteme de operare de tip server, sisteme de baze de date. De asemenea, se micșorează perioada de dezvoltare a aplicației deoarece unele componente, fiind furnizate de terțe părți nu mai trebuie dezvoltate și testate, doar integrate.
În dependență de furnizorul ales, cantitatea de servicii oferite în mod gratuit este suficientă în perioada de la lansarea produsului pe piață până în momentul când v-a începe să genereze profit.
La capitolul dezavantaje am putea menționa aspecte legate de securitatea datelor care ar putea fi depășite prin implementarea unui strat suplimentar de criptare al datelor. Un alt dezavantaj l-ar putea constitui diversele limitări pe care le impun furnizorii de MBaaS pentru a-și optimiza performanțele și costurile lor. Aceste limitări pot fi depășite prin particularizarea unor componente ale aplicației, sau pot fi detectate în procesul de proiectare al aplicației când se iau decizii despre utilizarea unor componente sau servicii din terțe părți și se studiază documentația tehnică a acestora.
Serviciu WEB
Un serviciu web este un sistem software proiectat să ofere comunicare între două dispozitive prin intermediul unei rețele.
Serviciile web au fost un răspuns la necesitatea apariției unei metode scalabile de comunicare între aplicații eterogene.
Un serviciu web comunică și schimbă date cu clienții prin intermediul protocolului HTTP, care este un protocol text, fără stare și care este înțeles sau poate fi implementat pe o varietate largă de sisteme. Clienții folosesc aceleași metode HTTP (GET, POST, PUT, DELETE) pe care le folosesc navigatoarele web, pentru a accesa resursele oferite de serviciu. Datele vehiculate între server și client trebuie să aibă același sens pentru ambele entități, prin urmare este necesar un format de serializare independent de platformă. Formatele XML sau JSON asigură această funcționalitate.
Pentru a fi performant și scalabil, un serviciu web trebuie proiectat respectând anumite principii de arhitectură. Prima constrângere este implementarea modelului client-server. O interfață uniformă separă clienții de server. Codul pentru client și pentru server poate fi implementat separat, în tehnologii total diferite, atâta timp cât se respectă interfața definită la început. Separarea rolurilor între client și server conduce la îmbunătățirea portabilității codului. De exemplu, clientul nu este preocupat de modalitățile de stocare a datelor utilizate de server, iar serverul nu trebuie să știe nimic despre interfața grafică a clientului.
Comunicarea dintre client și serviciul web trebuie să fie fără stare, aceasta însemnând că serverul care găzduiește serviciul web nu menține nici o informație despre client între cereri consecutive. Dacă este nevoie, o stare a sesiunii dintre client și serviciu este păstrată pe client folosind tehnologii specifice.
Răspunsurile primite de la serviciul web pot fi păstrate local o anumită perioadă de timp. În acest fel se reduce numărul de cereri către serviciul web, crescând viteza aplicației. De cele mai multe ori, serviciile web includ în răspuns informații despre perioada de valabilitate a răspunsului.
În scopul creșterii vitezei de răspuns și a scalabilitații unui serviciu web, acesta poate fi proiectat folosind o arhitectură multi-strat. Cererea unui client este analizată de un nivel al serviciului, dacă nu poate fi tratată, este pasată la nivelul superior ierarhic. Printre beneficiile arhitecturii multi-strat putem menționa echilibrarea încărcării, mecanisme de cache-ing intermediar, politici de securitate mai bune.
În prezent majoritatea companiilor din domeniul Tehnologiei Informației pun la dispoziția programatorilor servicii web prin intermediul cărora serviciile lor pot fi integrate în cadrul altor aplicații.
Single Page Application
Aplicațiile Single Page Application (SPA) sunt aplicații web care încarcă o singură pagină web și o actualizează dinamic ca răspuns la acțiunile utilizatorului. Acest tip de aplicații rulează într-un navigator web și sunt construite folosind tehnologii AJAX și HTML5 fără reîncărcări constante ale paginii. Acest lucru înseamnă că majoritatea activităților de procesare se întâmplă pe partea de client, prin urmare navigatorul trebuie să suporte și să permită rularea de cod Javascript.
Într-o aplicație web tradițională, de fiecare dată când pagina face un apel la server, acesta randează o nouă pagină web care declanșează redesenarea (eng. refresh) paginii în cadrul navigatorului web. În Figura 2-1 este ilustrat modul de funcționare al acestui tip de aplicații web.
Figura 2-6 Modul de funcționare al unei aplicații web tradiționale
Într-o aplicație de tip SPA, după încărcarea inițială a paginii, toate interacțiunile dintre client și server se fac prin intermediul apelurilor AJAX (Asynchronous JavaScript and XML). Aceste apeluri returnează date, de obicei în format JSON. Aplicația folosește aceste date pentru a actualiza conținutul paginii, fără a declanșa reîncărcarea ei. Figura 2-7 ilustrează acest mod de lucru.
Figura 2-7 Modul de funcționare al unei aplicații SPA
Un avantaj evident al aplicațiilor de tip SPA este pentru utilizatori o experiență mai fluidă, asemănătoare cu cea a aplicațiilor desktop, fără efectul deranjant al reîncărcării paginii. Un alt avantaj este o cantitate mai mică de date vehiculate în rețea, deci costuri mai mici pentru traficul de Internet.
Din punct de vedere arhitectural, în cadrul unei aplicații web de tip SPA există o separare clară între nivelul de prezentare (HTML + CSS) și cel logic (apeluri AJAX și răspunsuri JSON). Acest lucru face posibilă utilizarea șablonului arhitectural MVC (Model-View-Controller) la fel ca într-o aplicație desktop clasică.
Odată cu popularizarea standardului HTML5, multe aplicații care au fost migrate din mediul desktop în mediul web au fost proiectate sub forma unor SPA. Exemple elocvente în acest sens sunt Microsoft Office Online , Google Docs, Apple iCloud , Gmail.
Proiectarea sistemului de evidență automată a timpului
Arhitectura și descrierea generală a sistemului
Sistemul de evidență automată a timpului folosind tehnologia iBeacon este un sistem informatic complex compus din mai multe componente care comunică între ele folosind protocoale specifice schimbului de date prin intermediul rețelei Internet.
Prin sistem, înțelegem o colecție de componente software care îndeplinesc o funcție sau un set de funcții. Arhitectura unui sistem este organizarea componentelor software pentru a îndeplini funcții specifice.
În etapa de proiectare a arhitecturii sistemului de evidență a timpului am respectat principiile-cheie ale arhitecturii software:
Separarea preocupărilor (eng. Separation of concerns)
Principiul responsabilității unice (eng. Single Responsibility principle)
Principiul cunoștinței minime (eng. Principle of Least Knowledge)
Respectarea acestor principii de proiectare conduce la obținerea unei aplicații software scalabilă, extensibilă, cu costuri minime de dezvoltare, întreținere și operare.
Figura 3-1 Schema-bloc a sistemului de evidență a timpului
În Figura 3-1 este prezentată schema bloc a sistemului de evidență a timpului folosind telefoane mobile inteligente. Săgețile din figură indică modulele care comunică direct între ele. Sistemul a fost gândit să fie utilizat de către diverse organizații care doresc să monitorizeze timpul petrecut de către angajați în diverse locații. În procesul de proiectare s-a ținut cont de 2 funcționalități mari : cea de monitorizare, respectiv de colectare a datelor ce țin de timpul petrecut de către un angajat într-o anumită locație și cea de administrare a utilizatorilor, și analiză a datelor obținute, cea din urmă funcționalitate fiind disponibilă doar anumitor persoane din cadrul unei organizații.
Pentru a asigura aceste funcționalități, sistemul are patru componente, slab cuplate, care comunică între ele, două câte două. Primele două componente, respectiv aplicația-client pentru telefoane mobile și MBaaS-ul asigură prima funcționalitate cerută. De remarcat că prin MBaaS se înțelege totalitatea serviciilor oferite de furnizor precum și module de cod care fac procesări asupra datelor stocate. A doua funcționalitate este îndeplinită de serviciul web și portalul de configurare care este o aplicație web de tip SPA. Arhitectura aleasă asigură o cuplare slabă între componente ceea ce se traduce printr-o extensibilitate sporită a sistemului. De asemenea interdependența slabă între modulele permite rescrierea unui modul sau migrarea acestuia spre o altă tehnologie, în felul acesta asigurându-se optimizarea costurilor de dezvoltare și operare a sistemului. Un alt beneficiu al acestei arhitecturi este ușurința cu care sistemul va fi extins sau îmbunătățit. De exemplu, existența serviciului web pentru portalul de configurare asigură în viitor ușurarea creării de aplicații similare pentru alte platforme, fiind necesar doar codul pentru interfață, iar logica aplicației va fi furnizată de serviciul web.
Descrierea componentelor sistemului
MBaaS
Orice sistem software modern care oferă servicii personalizate în dependență de utilizator folosește în mod obligatoriu o bază de date. Pentru a respecta principiul separării preocupărilor , dar și din motive de scalabilitate și securitate, baza de date este separată de restul aplicației, și este sub forma unui sistem separat care comunică cu aplicația client prin intermediul rețelei Internet. În prezent există două mari tipuri de baze de date: de tip relațional și non-relațional.
Bazele de date relaționale se bazează pe modelul relațional al datelor propus de E.F. Codd în 1970.
Bazele de date non-relaționale au fost dezvoltate recent ca răspuns la necesitatea creării unor sisteme de stocare și regăsire a informațiilor foarte rapide pentru aplicațiile web de timp real. Deși există mai multe metode, majoritatea bazelor de date non-relațional stochează datele sub forma perechilor cheie-valoare și simulează organizarea datelor sub forma tabelelor relaționale.
În cazul platformelor mobile, pe piață a apărut conceptul de Mobile Backend as a Service (MBaaS) care oferă un mediu de stocare a datelor non-relațional și un set de servicii axate în jurul acestei funcționalități. Este un concept foarte util, deoarece permite dezvoltatorilor să-și construiască veritabile servere de aplicații care rulează în cloud cu efort puțin și investiții minime.
În cadrul sistemului de evidență automată a timpului folosind tehnologia iBeacon, pentru a răspunde la necesitatea prezenței unei baze de date dar și a unui server de aplicație pentru aplicația client care rulează pe dispozitivele mobile am decis să folosesc serviciile oferite de Parse. Parse este o subsidiară Facebook care oferă servicii de tip MBaaS pentru toate platformele mobile, pentru limbaje precum Javascript, C# (pentru aplicații web) dar și C/C++ (pentru aplicații din categoria Internet of Things).
Dintre serviciile oferite de Parse am utilizat baza de date non-relațională pentru stocarea de obiecte, SDK-ul pentru platforma Android pentru accesul la baza de date, respectiv introducerea, modificarea și ștergerea datelor, posibilitatea de a executa funcții înainte de introducerea, modificarea sau ștergerea datelor (conceptul de trigger), posibilitatea de a apela funcții care se execută în cloud (conceptul de cloud-code), posibilitatea de a rula, la intervale regulate de timp funcții în cloud (conceptul de job ).
În afara serviciilor menționate mai sus, la dispoziția programatorilor este pusă documentația tehnică a tuturor serviciilor oferite, posibilitatea de a crea, vizualiza și modifica baza de date prin intermediul unei aplicații web, posibilitatea de a depana interogările asupra bazei de date, posibilitatea de a consulta log-urile aplicației și posibilitatea de a edita și încărca codul care se va executa în cloud. Toate aceste servicii conexe au fost indispensabile în procesul de dezvoltare a aplicației.
Serviciile Parse sunt taxate în funcție de cantitatea consumată, totuși există o limită confortabilă până la care ele sunt furnizate în mod gratuit. Această limită este suficientă pentru întreg procesul de dezvoltare a aplicației, cât și pentru testarea ei, într-un mediu real folosind un număr suficient de utilizatori. Costurile generate în timpul operării pot fi estimate cu precizie mare, totuși ele nu vor depăși costurile suportate dacă s-ar alege varianta dezvoltării de la zero a infrastructurii hardware și software pentru serverul de aplicație.
La capitolul dezavantaje trebuie menționate aspecte legate de securitatea datelor. Datele nu sunt criptate atunci când sunt stocate, nici atunci când sunt transportate, chiar dacă se folosește protocolul HTTPS. Ar fi posibil de implementat un mecanism de negociere de chei între aplicația de telefon mobil și serverele Parse, apoi să fie utilizat un algoritm de criptare simetrică pentru securizarea datelor. Acest lucru însă nu este fezabil deoarece algoritmii de criptare și decriptare consumă multă putere de calcul, chiar dacă sunt implementați la nivel hardware (unele procesoare mai ieftine pentru telefoane mobile nu dispun de asemenea facilități). Necesitatea unei puteri de procesare mai mari se traduce într-un consum mai rapid al bateriei, respectiv o autonomie mai mică pentru dispozitivul respectiv ceea ce ar fi deranjant pentru utilizator.
Datele pe care le vehiculează aplicația-client și serverele Parse nu sunt atât de sensibile, prin urmare nu este justificată securizarea lor în timpul transferului.
Aplicație client
Componenta care va realiza efectiv evidența timpului petrecut de un angajat în cadrul unei anumite locații este aplicația care va fi instalată pe telefonul mobil al acestuia. Aplicația v-a fi dezvoltată pentru platforma Android, care are cea mai mare cotă de piață, conform Figura 2-1. Pentru a detecta beacon-uri, un dispozitiv mobil are nevoie de suport hardware și software dedicat. Astfel, din punct de vedere hardware, un telefon trebuie să fie dotat cu un receptor Bluetooth 4.0, iar din punct de vedere software, sistemul de operare al telefonului respectiv trebuie să aibă implementată stiva Bluetooth Low Energy (BLE).
În cadrul ecosistemului Android, suportul pentru această tehnologie a fost introdus odată cu versiunea 4.3, iar conform Tabel 2-1, versiunea minimă de SDK care permite accesarea protocolului BLE este 18. Prin urmare, pentru ca aplicația să fie disponibilă la un număr cât mai mare de posesori de telefoane inteligente cu Android, dar în același timp să îndeplinească funcționalitatea pentru care a fost proiectată, ea trebuie scrisă folosind Android SDK 18.
Aplicația trebuie să implementeze un modul care folosind protocolul BLE, să scaneze la intervale regulate și să detecteze beacon-urile din apropiere. Acest modul trebuie să fie eficient din punct de vedere al puterii de calcul consumate, dar și din punct de vedere al energiei consumate.
Așa cum am menționat în Arhitectura și descrierea generală a sistemului, aplicația client trebuie să comunice cu baza de date a MBaaS – ului pentru a salva acolo datele despre locațiile în care s-a aflat utilizatorul.
Aplicația trebuie să fie simplă, intuitivă și ușor de utilizat. Prin urmare, la proiectarea ei se v-a minimiza interacțiunea cu utilizatorul, urmărindu-se ca cele mai multe decizii să fie luate în mod automat.
Serviciu WEB
Serviciul WEB din cadrul sistemului de evidență automată a timpului are scopul de a oferi un set de apeluri prin intermediul cărora se poate configura sistemul sau se pot afla date despre utilizatorii sistemului. Interfața oferita de serviciu este independentă de platformă și limbaj, deci poate fi apelată din orice tip de aplicație. În cadrul sistemului, această interfață v-a fi apelată de către aplicația SPA de configurare și gestionare a sistemului.
Serviciul v-a prelua cererile clienților, le v-a autentifica și pe baza rezultatului autentificării v-a decide ce răspuns v-a întoarce clientului. Prin urmare, o funcție a sa este de a securiza accesul la datele pe care le produce sistemul.
Cererile clienților vor fi autentificate prin furnizarea de către aceștia a unui identificator de sesiune, care v-a fi obținut de către client ca răspuns la apelul de autentificare în cadrul serviciului. Din motive de securitate, datele despre sesiune vor fi păstrare și de client și de către server. Sesiunea clientului v-a fi validă doar o anumită perioadă de timp, dar se v-a prelungi în mod automat la fiecare cerere executată cu succes. La expirarea sesiunii, datele despre ea se distrug de către ambele părți. Clientul poate obține o sesiune nouă dacă se autentifică din nou.
Serviciul este singura entitate din cadrul sistemului care prin accesarea bazei de date poate întoarce rapoarte despre utilizatorii săi, în special rapoartele cu privire la timpul petrecut de angajați în locațiile monitorizate din cadrul organizației.
Protocolul HTTPS se v-a folosi pentru transferul datelor între client și server. Acesta este versiunea securizată a protocolului HTTP. În cadrul HTTPS datele vehiculate sunt criptate cu o cheie care a fost negociată în prealabil de către client și server la începutul sesiunii.
Tot din motive de securitate, toate apelurile oferite de serviciu vor folosi metoda POST pentru evitarea transferul de parametri prin intermediul URL-ului, evitarea constrângerilor legate de lungime, evitarea mecanismelor de cache-ing pe partea de client, evitarea înregistrărilor în istoricul navigatorului web.
Numele apelurilor din interfața expusă de server trebuie să sugereze acțiunea efectuată. Cererile și răspunsurile vor fi formulate în formatul JSON. Utilizarea acestui format crește performanțele aplicațiilor care îl folosesc prin faptul că este ușor serializabil și deserializabil și are un format simplu, apropiat de datele pe care le încapsulează. Dacă o aplicație web v-a folosi apeluri care întorc obiecte JSON, nu mai sunt necesare alte conversii de format deoarece obiectele native Javascript sunt și obiecte JSON. În alte limbaje de programare, chiar dacă JSON-ul nu este un format nativ, conversia către acest format se realizează cu un efort computațional minim.
Portalul de configurare al sistemului
Fiecare organizație care decide să implementeze sistemul de evidență automată al timpului folosind tehnologia iBeacon v-a avea la dispoziție o aplicație web prin care își poate configura și personaliza sistemul. Fiecare organizație v-a beneficia de un cont în cadrul portalului, existând posibilitatea ca ulterior să își creeze mai multe conturi care să ofere acces la portalul de configurare respectiv. Datele afișate și acțiunile puse la dispoziție de portal vor fi personalizate în funcție de organizație.
Aplicația web care v-a avea îndeplini rolul de portal de administrare și configurare al sistemului va fi de tip SPA, pentru a oferi utilizatorilor o experiență cât mai apropiată de aplicațiile desktop. De menționat că în prezent nu există alte tehnologii care să ofere rezultate similare.
Elementele de interfață vor fi de dimensiuni potrivite, pentru a putea utiliza aplicația de pe calculatoare dotate cu mouse și tastatură, dar și de pe dispozitive dotate cu ecrane tactile. De asemenea, interfața trebuie să se adapteze în mod automat la diverse dimensiuni de ecran.
Ca orice aplicație care oferă informații personalizate în dependență de utilizator, portalul de configurare v-a pune la dispoziția utilizatorilor o fereastră în care își pot introduce datele de acces în sistem. Dacă autentificarea v-a avea loc cu succes, utilizatorul v-a primi un identificator de sesiune care v-a fi stocat local. Acest identificator v-a fi folosit ulterior pentru autentificare, atunci când se comunică cu serviciul web. Stocarea locală (folosind tehnologii HTML5) asigură faptul că chiar dacă utilizatorul reîncarcă pagina, identificatorul de sesiune nu se pierde, prin urmare utilizatorul poate folosi aplicația în continuare, în caz contrar ar fi fost redirecționat spre ecranul de autentificare.
Prin intermediul portalului de configurare, organizațiile își pot defini locațiile pe care vor să le monitorizeze. O locație în cadrul sediului organizației este identificată printr-un beacon. Beacon-ul este identificat în sistem prin adresa MAC. O alternativă la adresa MAC o poate reprezenta combinația dintre UUID și identificatorii Major și Minor. S-a preferat prima variantă deoarece este mai simplă și mai ușor de explicat persoanelor non-tehnice (se pleacă de la premisa că sistemul v-a putea fi configurat direct de către personalul organizației, fără ajutor extern).
O altă funcționalitate oferită de portal este gestiunea angajaților care vor fi monitorizați. Există posibilitatea de a adăuga, șterge și dezactiva monitorizarea pentru anumiți angajați. Atunci când este adăugat un angajat nou, se generează un cod unic care îi v-a fi comunicat angajatului, pentru a-și activa aplicația de pe telefonul său mobil. Ștergerea unui angajat înseamnă că sistemul nu v-a mai accepta date despre locația sa, chiar dacă ele vor fi trimise în continuare. Datele existente nu vor fi șterse, vor fi păstrate în scop statistic.
Prin intermediul portalului, pot fi consultate statisticele produse prin prelucrare datelor trimise de aplicațiile instalate pe telefoanele angajaților. Statisticile pot fi consultate direct în aplicație, prin selectarea angajatului dorit, sau se pot genera rapoarte în format PDF care pot fi descărcate sau imprimate. S-a ales acest format deoarece este standartizat și există aplicații pentru vizualizarea documentelor de acest tip pe toate platformele software.
Tehnologia iBeacon permite aproximarea distanței dintre beacon și telefonul mobil care a detectat semnalul emis de acesta. În portal există posibilitatea de a genera un grafic care arată distanța dintre beacon și telefonul angajatului respectiv. Deoarece tehnologia iBeacon încă nu este matură, graficul respectiv are un grad mare de subiectivitate și trebuie interpretat ca atare.
Proiectarea componentelor sistemului
Baza de date
Baza de date este o componentă-cheie în cadrul oricărui sistem informatic. De dânsa depind în mare măsură performanțele de ansamblu ale sistemului. O bază de date modernă, pe lângă funcțiile elementare de stocare și acces la date trebuie să ofere și instrumente prin care să permită prelucrarea și manipularea datelor în cadrul unor blocuri structurate de cod, executat pe mașina care gestionează baza de date. Conceptul de mai sus permite reducerea cantității de date vehiculate prin intermediul unei rețele de transfer date, respectiv timpi de așteptare mai mici pentru clienți.
În cadrul sistemului de evidență automată a timpului folosind tehnologia iBeacon s-a decis utilizarea bazei de date non-relaționale (referită în continuare ca Parse) oferite de Parse – furnizorul de MBaaS. În cadrul acestui tip de soluții de stocare, datele sunt păstrate sub formă de obiecte, obiectele fiind instanțe ale unor clase. Fiecare obiect este identificat în mod unic în cadrul unei clase de un identificator, numit objectId, generat în mod automat de sistem la crearea obiectului. Identificatorul obiectului este generat în mod aleatoriu, de tip șir de caractere, de lungime 10, compus din literele alfabetului latin a-z, A-Z și cifrele arabe 0-9. Pe lângă câmpul objectId, sistemul generează implicit alte trei câmpuri: createdAt – un câmp de tip dată calendaristică, gestionat de sistem, unde este stocată data și timpul creării obiectului, updatedAt – câmp de tip dată calendaristică, gestionat de sistem, unde este stocată data și timpul ultimii actualizări a obiectului și câmpul ACL – un câmp gestionat de utilizator unde este stocat un obiect de tip Parse ACL care păstrează drepturi de acces la obiect. Deoarece gestionarea accesului la baza de date se face în cadrul altui modul software, acest câmp nu va fi utilizat.
Între obiecte pot exista dependințe de tipul unu-la-unu (1:1), unu-la-mulți (1:M) sau mulți-la-mulți (M:M). Parse pune la dispoziție trei metode pentru modelarea relațiilor dintre obiecte: pointeri, tablouri și prin intermediul obiectelor de tip Relations. Prin intermediul pointer-ilor pot fi modelate relații de tip unu-la-unu și unu-la-mulți. Pointerii din Parse au același sens ca și pointerii din programarea orientată obiect, iar dacă ne referim la sisteme de stocare a datelor de tip relațional, sunt echivalentul cheii străine. Prin intermediul tablourilor pot fi modelate relații de tip unu-la-mulți și mulți-la-mulți. Acest mecanism constă în existența unui tablou de obiecte-fii în cadrul obiectului-părinte. Ultima metodă este folosită doar pentru modelarea relațiilor de tip mulți-la-mulți și este asemănătoare cu metoda a doua, cea a tablourilor.
În cadrul sistemului, pentru modelarea dependențelor dintre entitățile bazei de date am decis să folosesc metoda pointer-ilor deoarece oferă cea mai mare flexibilitate și are echivalent atât în programarea orientată obiect cât și în cadrul sistemelor de baze de date relaționale.
Un aspect important care trebuie menționat este cel legat de păstrarea de către Parse a datelor calendaristice. Astfel, spre deosebire de alte sisteme, Parse interpretează toate datele calendaristice venite de la clienți ca având fusul orar UTC (eng. Coordinated Universal Time – Timpul Universal Coordonat) și le servește tot în acest mod. SDK-urile puse la dispoziție de Parse fac o conversie implicită a fusului orar atunci când trimit spre salvare date calendaristice. Deși poate părea o restricție, este totuși un lucru benefic deoarece lasă la latitudinea clienților să decidă fusul orar afișat, în dependență de zona geografică în care se află.
Câmpurile obiectelor din Parse pot fi de tip șir de caractere, numeric, logic (boolean), dată calendaristică sau de tip obiect. Există câteva tipuri predefinite de obiecte prin intermediul cărora se pot modela relațiile (obiecte de tip Pointer și Relations), sau se pot stoca coordonate geografice (obiect de tip GeoPoint) sau fișiere (obiect de tip File). De asemenea se pot stoca și obiecte cu proprietăți adăugate dinamic, chiar dacă obiectul nu aparține unei clase existente. Acest lucru este posibil datorită existenței mecanismului de lazy initialization (creare întârziată) a claselor, implementat în Parse. În Figura 3-2 este prezentată structura bazei de date a sistemului.
Înainte de a fi stocate într-un mediu persistent, Parse serializează obiectele în formatul JSON. Relațiile dintre obiecte, reprezentate prin pointeri, la fel sunt serializate. Pointer-ul în Parse este reprezentat printr-un obiect special.
În următoarea secvență de cod este afișată structura unui obiect din clasa TrackingRecord, pregătit pentru inserare în baza de date (lipsesc câmpurile implicite ale obiectelor Parse, ele vor fi adăugate în momentul inserării) serializat în formatul JSON. Se observă modul special de serializare a dependențelor dintre obiecte (obiectele Pointer) dar și modul de stocare al datelor calendaristice.
Cloud Code
În cadrul sistem informatic eterogen componentele care rulează în diverse medii, au nevoie să facă schimb de date între ele. Schimbul de date se face prin intermediul unui canal de comunicare care introduce timpi de așteptare proporționali cu dimensiunea datelor care trebuie schimbate. O altă sursă de întârzieri o reprezintă timpii mari de prelucrare a datelor de către clienții cu resurse limitate de calcul. Pentru a rezolva aceste probleme, s-a făcut apel la facilitatea oferită de furnizorul de MBaaS de a rula module de cod structurat în cloud pentru filtrarea și prelucrarea primară a datelor.
Modulelor de cod executate în cloud-ul Parse, sunt structurate în funcții. O funcție poate primi parametri și întoarce un rezultat de tip succes cu eventuali parametri dacă nu au intervenit erori în cadrul execuției sale, sau întoarce un răspuns de tip eroare cu codul și mesajul de eroare respectiv.
O funcție poate manipula datele din baza de date Parse, poate prelucra date trimise de utilizator prin intermediul parametrilor sau date preluate din alte surse prin intermediul cererilor HTTP. Nu există restricții asupra tipului de prelucrări efectuate, doar restricții în ceea ce privește timpul de execuție și cantitatea de date prelucrată.
Pentru a crește performanțele și securitatea sistemului, în cadrul Parse au fost implementate 4 categorii de funcții care rulează în cloud:
o funcție care este apelată de sistem la intervale regulate (Background Job)
funcții care sunt apelate de sistem în mod automat la modificări asupra bazei de date (triggers)
funcții apelate de alte componente ale sistemului pentru manipularea datelor
funcții utilitare, inaccesibile altor componente.
Cea mai importantă funcție care rulează în cloud, dintre cele menționate, este Background Job-ul sistemului, care este pornit automat, la sfârșitul unei zile. Acesta trebuie să citească toate obiectele din clasa TrackingRecord adăugate în ziua respectivă și pe baza lor, să adauge sau să modifice obiectele din clasele TotalPerUser și TotalPerBeacon. De menționat că în cazul clasei TrackingRecord, câmpurile DateOfRecord și createdAt nu sunt neapărat egale. Câmpul DateOfRecord este inițializat atunci când aplicația de pe telefonul angajatului creează un obiect de tip TrackingRecord, iar câmpul createdAt este inițializat în momentul când obiectul este salvat în baza de date. Dacă aplicația nu a avut acces la rețea să trimită obiectele respective, câmpurile vor avea valori diferite. Bazându-se pe valorile câmpurilor menționate, logica implementată în cadrul Background Job-ului decide dacă trebuie să creeze înregistrări noi sau să le actualizeze pe cele existente.
O altă categorie de funcții o reprezintă funcțiile care se apelează în mod automat la inserarea de date. Aceste funcții au fost implementate pentru clasa TrackingRecord și validează înregistrările trimise de către aplicațiile instalate pe telefoanele angajaților. Din necesitatea obținerii unei performanțe sporite pentru optimizarea consumului de baterie, aplicațiile de pe telefoanele angajaților trimit datele direct în baza de date. În cazul celorlalte componente, accesul și manipularea datelor se face prin apelarea funcțiilor special create. În acest mod, restul componentelor sistemului nu trebuie să cunoască ierarhia de clase a bazei de date având loc decuplarea aplicațiilor client de baza de date.
Detaliile de implementare vor fi tratate în capitolul următor iar codul poate fi consultat în secțiunea de anexe a lucrării.
Aplicație client pentru evidența timpului folosind tehnologia iBeacon
În cadrul sistemului de evidență automată a timpului folosind tehnologia iBeacon, datele legate de timpul de intrare și de ieșire ale unui angajat dintr-o locație monitorizată cu beacon-uri vor fi colectate de către o aplicație instalată pe telefonul mobil al acestuia.
Aplicația va fi dezvoltată pentru platforma Android, în limbajul Java. În Figura 3-3 sunt reprezentate cele două componente majore ale aplicației: o componentă care reprezintă interfața grafică cu utilizatorul și o componentă care reprezintă un serviciu Android care rulează în foreground.
În cadrul sistemului de operare Android există două moduri în care poate rula un serviciu: în mod background și în mod foreground. Serviciile Android care se execută în mod background pot fi oprite de sistemul de operare atunci când sunt necesare resurse (memorie, putere de calcul) pentru alte aplicații sau procese ale sistemului de operare. Un serviciu aflat în mod foreground nu va fi oprit de sistemul de operare atunci când resursele sunt insuficiente deoarece consideră că utilizatorul știe de existența lui, deci nu poate fi un candidat de la care să obțină resurse suplimentare de memorie. Un astfel de serviciu va afișa în mod obligatoriu o notificare în bara de stare a telefonului pe toată durata sa de execuție.
Pentru ca aplicația client s-a monitorizeze încontinuu timpii în care un angajat își schimbă locația, serviciul aplicației trebuie să se execute în modul foreground pentru a nu fi oprit la momente aleatorii de timp de către sistemul de operare.
Figura 3-3 Diagrama de componente a aplicației client
Interfața grafică a aplicației trebuie să fie simplă și intuitivă și să ofere doar câteva funcții care sunt absolut necesare funcționării ei. În diagrama cazurilor de utilizare ale interfeței grafice ale aplicației din Figura 3-4 sunt prezentate și principalele ei funcționalități.
Figura 3-4 Cazuri de utilizare ale interfeței grafice
În plus față de facilitățile descrise în diagrama cazurilor de utilizare, interfața grafică va oferi suport pentru înregistrarea aplicației în cadrul sistemul de evidență automată a timpului.
Serviciul aplicației poate fi pornit doar din interfață și doar de către utilizator. Serviciul va continua să se execute independent de aplicație chiar dacă utilizatorul a închis interfața grafică. Oprirea sa se face deschizând din nou interfața grafică.
În Figura 3-5 este prezentată diagrama cazurilor de utilizare ale serviciului. Pe lângă activitățile legate de scanarea beacon-urilor și transmiterea informațiilor despre evidența timpului și a locației, serviciul va porni emițătorul Bluetooth al telefonului atunci când are nevoie să efectueze o nouă scanare a beacon-urilor din apropiere. Accesul la comunicațiile Bluetooth este esențial pentru buna funcționare a aplicației.
Deoarece aplicația va fi implementată în limbajul Java, codul ei trebuie structurat în pachete. În Figura 3-6 este prezentată diagrama de pachete a aplicației.
Figura 3-6 Diagrama de pachete a aplicației
Pachetul rădăcină al aplicației (com.iraileanu.timetracking) conține patru pachete. Pachetul com.iraileanu.timetracking.app va conține clase cu cod apelabil de toate entitățile aplicației. În pachetul com.iraileanu.timetracking.db vor fi clasele responsabile de comunicarea cu MBaaS-ul aplicației și clasele ce vor fi responsabile de stocarea locală a datelor și a setărilor aplicației. În sub pachetul model vor fi clase ce vor modela entitățile bazei de date. În următorul pachet (com.iraileanu.timetracking.service) vor fi clasele care aparțin serviciului aplicației și clasele care vor apela rutinele Android pentru scanarea de beacon-uri. Ultimul pachet va conține clasele prin intermediul cărora va fi implementată interfața grafică a aplicației.
În afară de codul Java, o aplicație Android mai are nevoie de fișiere de resurse unde sunt definite textele ce vor fi afișate în interfața grafică (fișierul strings.xml), fișierele xml care conțin definițiile obiectelor care compun interfața grafică (fișiere layout) și fișierul de configurare al aplicație (AndroidManifest.xml). Acest fișier conține drepturi de acces ale aplicației la resursele sistemului de operare, informații despre interfața pe care trebuie să o afișeze imediat după pornirea aplicației, informații despre numele și versiunea aplicației, alte informații de configurare.
Serviciul web al sistemului
Serviciul web din cadrul sistemului de evidență automată a timpului folosind tehnologia iBeacon are scopul de a intermedia comunicarea dintre aplicația web de configurare și baza de date din cadrul MBaaS-ului.
Serviciul va pune la dispoziția clienților interesați un șir de metode web prin care pot fi manipulate datele din cadrul bazei de date a sistemului. În același timp, serviciul web va fi responsabil de controlul accesului la date, în acest scop implementând un sistem de autentificare și verificare a identității clienților.
Serviciul web va fi construit folosind tehnologiile ASP.NET WebAPI 2.0, în limbajul C# și .NET Framework 4.5. La definirea arhitecturii sale vor trebui respecte constrângerile impuse de tehnologia pe baza căruia este construit. Una din primele constrângeri ale acestei tehnologii este că trebuie să ruleze pe un server Microsoft IIS. În Figura 3-7 este arătat modul în care serviciul web comunică cu clienții prin intermediul cererilor și răspunsurilor folosind protocolul HTTP.
Figura 3-7 Modul de funcționare al serviciului web
Tehnologia WebAPI 2.0 permite construirea de servicii web care respectă arhitectura REST. REST este un set de reguli pentru arhitectura unui serviciu web care îi permit să fie scalabil. Serviciile de tip REST fac schimb de date folosind formatele XML, JSON, ATOM (derivat din XML). Pentru serviciul REST din cadrul sistemului de evidență automată a timpului s-a ales formatul JSON, avantajele sale fiind prezentate în subcapitolul 3.2.3.
Figura 3-8 Arhitectura serviciului web
În Figura 3-8 este reprezentată schematic arhitectura serviciului web. Serviciul a fost structurat pe trei nivele. Primul nivel (Web Layer) este cel care expune clienților interfața serviciului și preia cererile lor. O cerere preluată este trimisă nivelului imediat următor (Business Layer) unde este autentificată și prelucrată. Răspunsul la cerere este formulat făcându-se apel la baza de date prin intermediul Data Access Layer. Schimbul de date între aceste nivele se realizează folosind modele. Un model este o clasă care încapsulează date despre o entitate a bazei de date sau în cazul serviciului web – date despre cererea unui client.
În cadrul unui proiect scris în limbajul C#, folosind .NET Framework, codul se organizează în biblioteci reutilizabile (dll-uri). Astfel, o funcționalitate a programului se separă într-o bibliotecă separată. O bibliotecă conține unul sau mai multe spații de nume (namespace-uri). Codul din cadrul unei biblioteci poate fi vizibil și apelabil din cadrul altor biblioteci sau poate fi apelabil doar în cadrul bibliotecii, în dependință de modificatorii de acces ai claselor. În acest fel, modulele de cod pot fi dezvoltate și testate independent și se asigură reutilizarea codului.
În Figura 3-8 sunt reprezentate componentele serviciului web, fiecare componentă fiind într-o bibliotecă separată. Cu săgeți sunt reprezentate interacțiunile dintre componente.
Figura 3-9 Bibliotecile componente și namespace-urile serviciului web
TimeTrackingRestService.dll este componenta Web Layer a serviciului web. Această componentă comunică cu serverul IIS de la care preia cererile trimise spre acesta, pentru serviciul web. Comunicarea cu IIS se face folosind clase specializate din cadrul bibliotecii .NET. Odată preluată, o cerere este analizată și rutată spre o clasă controller, pentru a fi tratată. Regulile de rutare se încarcă în momentul pornirii execuție serviciului web și nu pot fi modificate în timpul rulării. Astfel, în cadrul serviciului web, șablonul regulii de rutare este următorul:
"api/{controller}/{action}"
Prin urmare, toate apelurile pe care le va trata serviciul vor avea rădăcina /api , urmată de numele controller-ului, numele acțiunii și eventual, o listă de parametri. De exemplu, un apel de tip POST, la adresa
'/api/employee/getAllEmployees',
va fi rutat către clasa EmployeeController și va fi tratat de către metoda GetAllEmployees, dacă aceasta este marcată cu atributul [HttpPost] (atribut care desemnează tipul de cereri tratate de către o metodă). În acest mod, se obțin url-uri semantice pentru apelurile pe care le suportă serviciul. Acestea descriu într-o manieră evidentă acțiunea îndeplinită de serviciu și pot fi folosite la generarea automată, într-o aplicație, a unui set de clase pentru accesul la date.
Datele trimise odată cu apelul POST trebuie să fie în format JSON, iar metoda GetAllEmployees va primi un obiect de tipul AllEmployeesRequestModel cu parametrii necesari pentru tratarea cererii. Conversia dintr-un șir de caractere în format JSON într-un obiect instanță a unei clase C# se face în mod implicit de către serviciu, folosind clase specializate, specificate în cadrul obiectelor de configurare ale serviciului web. După tratarea unei cereri, se formulează un răspuns care este trimis clientului tot în format JSON, conținând datele cerute sau un mesaj de eroare dacă cererea nu a putut fi îndeplinită.
Tratarea efectivă a cererilor este făcută în componenta RestServiceBusinessLayer.dll care conține logica aplicației. Dacă sunt necesare date din baza de date, se face apel la clasele și metodele specializate din cadrul componentei RestServiceDataLayer.dll. Comunicarea între componentele serviciului web se face prin intermediul modelelor, care sunt definite în RestServiceModels.dll. Serviciul mai conține un dll, numit RestServiceReportingService.dll, care este responsabil de generarea de rapoarte în format pdf. Deși funcția îndeplinită de el face parte din logica aplicației, datorită specificității sale, s-a decis separarea ei în cadrul unei biblioteci independente.
Structurarea codului serviciului pe trei nivele ușurează munca de testare și depanare a eventualelor erori, crește gradul de reutilizare a codului, permite adăugarea sau modificarea ușoară a unor funcții, de exemplu schimbarea mecanismului de autentificare a cererilor, sau introducerea unui mecanism de validare a datelor.
Aplicația web de configurare a sistemului
Pentru a consulta datele generate de sistemul de evidență automată al timpului folosind tehnologia iBeacon, o organizație are nevoie de o aplicație dedicată care să faciliteze acest lucru. În acest scop, se va crea o aplicație web, de tip Single Page Application care va fi responsabilă de funcționalitatea menționată anterior.
Aplicația va fi construită folosind tehnologii web și este destinată să ruleze în navigatoarele web care suportă tehnologii HTML5.
Spre deosebire de o aplicație web clasică, unde pentru navigare se pot utiliza link-uri, care redirectează utilizatorul spre o altă pagină, în cadrul unei aplicații web de tip SPA acest lucru nu este posibil. Prin urmare, se va utiliza masiv limbajul Javascript pentru a suplini această funcționalitate.
Deoarece scopul final al unei aplicații web de tip SPA este să ofere utilizatorului o experiență fluidă, asemănătoare aplicațiilor desktop, se impune utilizarea unor principii de la programarea aplicațiilor desktop, și anume modelul MVC (Model-View-Controller).
Datorită specificității tehnologiilor de programare web (limbajele sunt interpretate în momentul randării pagini web), implementarea MVC în cadrul unei aplicații web diferă de modelul tradițional. Pentru a facilita dezvoltarea de aplicații web folosind acest șablon, sunt disponibile mai multe Framework-uri Javascript. Fiecare introduce diverse concepte de programare și adaptează șablonul MVC la ele.
Pentru aplicația de configurare a sistemului de evidență al timpului s-a decis utilizarea Framework-ului BackboneJS care deși nu este cea mai completă bibliotecă din punctul de vedere al funcționalităților oferite și a conceptelor implementate, oferă posibilitatea de a manipula comportamentul până la nivelul arborelui DOM, ceea ce este încapsulat în cadrul altor biblioteci similare. BackboneJS are nevoie ca dependințe de jQuery, una dintre cele mai răspândite biblioteci de Javascript și de UnderscoreJS, o bibliotecă care oferă un șir de metode pentru lucrul cu colecții de date. Aceste biblioteci au fost utilizate și în cadrul altor aspecte ale aplicației.
Pentru a facilita utilizarea aplicației pe diverse dispozitive cu diverse dimensiuni de ecran, dar și pentru a construi o interfață grafică prietenoasă cu utilizatorul se va folosi biblioteca Bootstrap, care conține un șir de clase CSS pentru stilizarea elementelor HTML dar și pentru scalarea lor la diferite dimensiuni ale porții de afișare.
BackboneJS introduce conceptul de modele – obiecte care conțin proprietăți (perechi de tipul cheie-valoare) și care pot declanșa evenimente la modificarea lor, colecții – un grup de modele, împreună cu un șir de funcții pentru manipularea lor și un șir de evenimente declanșate în momentul modificării, și view-uri care sunt responsabile de tratarea evenimentelor. De menționat că în cadrul BackboneJS, un view este echivalent cu controller-ul din cadrul MVC, iar rolul de view propriu zis (nivelul de prezentare) este înlocuit de un șablon UnderscoreJS (Underscore Template) scris în limbaj HTML cu elemente specifice care permit injectarea de cod Javascript necesar la atașarea datelor ce vor fi randate. Datele atașate șabloanelor pot proveni din cadrul unei colecții sau pot fi modele independente. La nivel conceptual, o aplicație SPA care folosește BackboneJS este compusă din 2 fișiere, unul HTML și unul Javascript. În următoarele secvențe de cod este ilustrată o structură simplă, pentru o aplicație SPA care folosește BackboneJS pentru structurarea codului.
În prima secvență de cod, care este un fișier HTML se remarcă structura de bază a unui document HTML. În secțiunea body a acestuia este prezent un singur element de tip div identificat printr-un id, în interiorul căruia va fi randată aplicația web. Scriptul care urmează imediat, este de tip text/template, și reprezintă un șablon pe baza căruia se va construi un view al aplicației.
În al doilea fișier este redat codul minim necesar pentru a compila șablonul, iar rezultatul să fie pus în interiorul elementului identificat prin id-ul myDisplayArea. Codul Javascript se va executa imediat după interpretare (este încadrat în $()).
Se remarcă modul de creare al unui view Backbone (prin extinderea obiectului Backbone.View) , suprascrierea proprietăților (el, template) și a funcțiilor (initialize(), render()). În cadrul metodei render() se observă modul în care se transmite modelul pe baza căruia va fi randat șablonul.
Prima instanțiere a unui obiect derivat din clasa Backbone.View înseamnă pornirea unei aplicații web de tip SPA care folosește BackboneJS.
Conceptul prezentat mai sus stă la baza aplicației. Toate datele care sunt afișate utilizatorului sunt furnizate prin intermediul apelurilor la serviciul web al sistemului. Apelurile sunt realizate asincron, prin intermediul metodei $.ajax() din biblioteca jQuery. Atunci când sunt primite, datele sunt transformate în modele, iar modele sunt stocate local în cadrul colecțiilor.
Implementarea sistemului de evidență al timpului
4.1. Configurarea MBaaS
Procesul de configurare al MBaaS-ului începe prin crearea unui cont de utilizator al platformei Parse (furnizorul de soluții MBaaS). Prin crearea contului, acceptăm în mod implicit termenii și condițiile de utilizare ale platformei.
După crearea contului, Parse pune la dispoziția utilizatorilor o aplicație web (Figura 4-1) prin care poți să îți configurezi serviciile de care ai nevoie. De asemenea, sunt puse la dispoziție identificatorul aplicației și cheile necesare pentru a putea folosi serviciile Parse din cadrul altor platforme (Android, .NET, Javascript, interfața REST, etc.).
Figura 4-1 Interfața aplicației web pentru configurarea serviciilor Parse
Tot din aplicația web (Figura 4-2) poate fi configurată ierarhia de clase a bazei de date, și pot fi consultate înregistrările existente.
Figura 4-2 Interfața aplicației web pentru configurarea bazei de date
Un alt pas important care trebuie făcut la etapa de configurare a MBaaS-ului este planificarea intervalului de execuție al background-job – ului responsabil de calcularea timpului cât un utilizator s-a aflat în proximitatea unui beacon. În Figura 4-3 este prezentată interfața de configurare a acestui tip de funcție, care se va executa la sfârșitul fiecărei zile.
Figura 4-3 Interfața de configurare a background-job – ului sistemului
Din aplicația web pot fi consultate log-urile produse de aplicație, cât și versiunea curentă de cloud code aflată în producție.
4.2. Modulele de cloud code
Un modul de cloud code reprezintă un set de funcții scrise în limbaj Javascript, destinat să ruleze în cloud, pe serverele Parse. Funcțiile din acest modul au rolul de a decupla aplicațiile de structura internă a bazei de date oferită de Parse. Din punct de vedere al vizibilității, există funcții care pot fi apelate din exterior, declararea cărora trebuie să respecte structura definită în următoarea secvență de cod, și funcții care sunt vizibile doar în cadrul modulului, declararea cărora este identică cu modul de declarare a funcțiilor în limbajul Javascript. Funcțiile vizibile din exterior, pot fi apelate folosind SDK-ul pus la dispoziție de Parse pentru platforma respectivă.
Așa cum se observă din secvența de mai sus, pentru a defini o funcție vizibilă din exterior, se face apel la funcția Parse.Cloud.define(), care introduce într-un tabel intern o pereche sub forma nume funcție – funcție. Funcția primește două obiecte ca parametri: primul parametru numit de obicei request conține informații despre apelantul funcției, inclusiv lista de parametri ce vor fi transmiși funcției, iar al doilea parametru, numit de obicei response care este o instanță a clasei Parse.Promise care este echivalentul în Javascript al rezultatului unui task asincron. Toate funcțiile Parse apelabile din exterior sunt asincrone și returnează imediat. Rezultatele sunt trimise clientului atunci când asupra parametrului al doilea al funcției (response) se apelează fie metoda success() dacă funcția s-a executat cu succes, fie error() dacă au intervenit erori în procesul de execuție al funcției.
Funcțiile native Parse pentru acces la baza de date sunt asincrone și returnează o instanță a clasei Parse.Promise. Accesarea rezultatelor întoarse de o astfel de funcție se poate face în două moduri. Un mod este prezentat în secvența de mai sus. Funcției find() i se transmite ca parametru un obiect conținând două funcții, una apelabilă în caz de succes și una care va fi apelată în caz de eroare. Al doilea mod de accesare al rezultatelor este prin apelarea unei metode (then()) din clasa Parse.Promise disponibilă în obiectul returnat de o funcție asincronă, așa cum este arătat în următoarea secvență de cod.
Primul parametru al funcției then() este o funcție sau un pointer la o funcție care primește ca parametru datele returnate de funcția fiind() și care se apelează în caz de succes. Al doilea parametru este o funcție sau un pointer la o funcție care se apelează în caz de eroare și care are ca parametru un obiect cu detaliile erorii.
Modulul de cloud code poate fi dezvoltat cu orice editor de text. S-a preferat utilizarea editorului Notepad++ deoarece are suport pentru evidențierea sintaxei, identarea codului și sugestii de auto-completare pentru limbajul Javascript.
Pentru a încărca pe server modulele de cod se utilizează un utilitar furnizat de Parse care, prin intermediul unei linii de comandă încarcă și înlocuiește versiune curentă de cod aflată în producție cu noua versiune.
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Sistem de Evidenta Automata a Timpului Folosind Tehnologia Ibeacondocx (ID: 155220)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
