Tuesday, January 20, 2015

Procesoare de șabloane pentru dezvoltare web în Java

(Publicat în revista Today Software Magazine, Numărul 23, Mai 2014: http://www.todaysoftmag.ro/article/882/procesoare-de-sabloane-pentru-dezvoltare-web-in-java)

Îmulte dintre proiectele informatice întâlnite avem de-a face cu situaţii în care trebuie să procesăm text, să generăm rapoarte, scripturi sau cod sursă. Adeseori, aceste probleme pot fi rezolvate cu ajutorul unor unelte numite procesoare de șabloane. Totuși, cel mai des întâlnit scenariu pentru utilizarea procesoarelor de şabloane este acela al dezvoltării de aplicaţii web, unde s-a observat nevoia separării logicii aplicaţiei de prezentare.
În cazul aplicaţiilor web dezvoltate cu tehnologii Java, standardul pentru partea de prezentare a fost mult timp JavaServer Pages, care are trăsăturile unui procesor de șabloane. Marele neajuns al acestei tehnologii este posibilitatea inserării debusiness logic în codul de prezentare. Astfel, avem posibilitatea să inserăm în documentul JSP scriptlets sau chiar blocuri de cod Java. Deși acest lucru ne poate ajuta în anumite situații, codul devine în mod rapid mai complex și greu de întreținut. Mai mult decât atât, această practică încalcă principiul design pattern-ului MVC.
Din cauza neajunsurilor de acest gen, JSP a pierdut teren semnificativ în favoarea altor procesoare de şabloane, care sunt folosite în tot mai multe proiecte, sporind productivitatea dezvoltatorilor şi calitatea produselor. Proiectele despre care vom discuta ne ajută să creăm cu ușurință conținut dinamic, combinând șabloanele cu modelul de date, pentru a produce documente rezultat. Șabloanele sunt scrise într-un limbaj de templating, iar documentele rezultate pot reprezenta orice fel de text formatat.
Pe lângă procesoarele deja consacrate, cum ar fi Apache Velocity sau FreeMarker, în ultimii ani a fost lansată o varietate de noi produse de acest gen, care oferă funcţionalităţi diverse. În continuarea acestui articol vom analiza patru produse disponibile gratuit pentru uz comercial, încercând să realizăm o comparaţie a acestora.

Spring MVC şi procesoarele de şabloane

Când ne gândim la dezvoltarea unei aplicaţii web cu ajutorul tehnologiilor Java, unul dintre primele lucruri pe care le facem este să alegem un framework MVC. Practica ne-a arătat că Spring MVC este unul dintre cele mai populare framework-uri web, iar în acest articol vom analiza utilizarea procesoarelor de şabloane din perspectiva integrării cu acesta. Pentru a ilustra anumite trăsături ale fiecărui procesor prezentat, vom dezvolta o aplicaţie web simplă, ce va fi compusă din două pagini: una care afișează o listă de produse și alta care afișează detaliile unui produs.

Apache Velocity

Velocity (http://velocity.apache.org/) este un proiect distribuit sub licenţă Apache Software License, care se bucură de o mare popularitate printre dezvoltatorii de aplicaţii Java. Deşi este utilizat de cele mai multe ori în context web, nu suntem limitaţi să folosim produsul doar pentru acest tip de proiecte. Poate fi utilizat fie ca un utilitar de sine stătător pentru generare de cod sursă şi rapoarte, fie ca o componentă integrată în alte sisteme.
Asemeni altor procesoare de şabloane, Velocity a fost proiectat astfel încât designerii web să poată lucra în paralel cu programatorii Java. Astfel, Velocity ne ajută să despărțim codul Java de codul paginilor web, oferind o alternativă viabilă tehnologiei JSP.

Velocity Template Language

Apache Velocity se bucură de un limbaj de scripting propriu, numit Velocity Template Language (VTL), care este puternic şi flexibil. Autorii Velocity anunţă cu mândrie că flexibilitatea produsului lor este limitată doar de creativitatea utilizatorului. VTL a fost creat cu scopul de a oferi cea mai simplă şi curată cale pentru a încorpora conţinut dinamic într-o pagină web.
Velocity foloseşte referinţe pentru a îngloba conţinut dinamic în paginile web, iar unul dintre tipurile de referinţe este reprezentat de către variabile. Acestea pot referi obiecte definite în codul Java sau pot primi valori chiar în interiorul paginiiweb, prin intermediul unei declaraţii VTL. O astfel de instrucţiune începe cu un caracter #, după cum putem observa în exemplul următor:

#set( $magazineUrl = "http://www.todaysoftmag.com/" )

Integrarea cu Spring MVC

Spring MVC are suport nativ pentru procesorul de șabloane despre care discutăm, și în consecință integrarea acestora este un proces simplu. Presupunând căfolosim Maven pentru crearea proiectului, alegem arhetipul maven-archetype-webapp din grupul org.apache.maven.archetypes. Fără a enumera toate dependințele Maven necesare, menționăm totuși că avem nevoie de artefactele velocity și velocity-tools din grupul org.apache.velocity. Codul sursă al proiectului exemplu poate fi descărcat de la următoarea adresă: https://springvelocity.googlecode.com/svn/trunk.
După ce am declarat în web.xml servlet-ul DispatcherServlet care va gestiona toaterequest-urile și am definit fișierul servlet-context.xml cu toate elementele specifice Spring, putem declara bean-urile pentru lucrul cu Velocity. În primul rând, avem nevoie de un bean cu id-ul velocityConfig, căruia îi vom transfera calea relativă la care se vor găsi șabloanele pentru paginile aplicației:



Apoi, declarăm un view resolver, care primește mai multe proprietăți. Clasa care va determina tipul acestui bean trebuie să implementeze interfața ViewResolver și are ca principal rol găsirea view-urilor după nume. Cea mai interesantă proprietate a acestui bean este layoutUrl. Aceasta reprezintă numele șablonului care va stabili layout-ul general:


De asemenea, Velocity are capacitatea de a face caching șabloanelor folosite, lucru specificat prin proprietatea cache.
Acum că am configurat aplicația astfel încât partea de vizualizare să fie reprezentată prin șabloane Velocity, putem să vedem cum arată aceste șabloane. Partea cea mai interesantă a șablonului care determină layout-ul general este prezența variabilei speciale $screen_content. Aceasta va conține la runtimerezultatul procesării șablonului corespunzător view-ului returnat de controller-ul Spring MVC. În cazul aplicației noastre există un singur controller, care poate returna fie view-ul list, fie view-ul detailsȘablonul corespunzător view-ului list este list.vm și are următorul conținut:


#foreach($product in $products)
#end


În blocul de mai sus observăm cum iterăm o colecție și cum accesăm proprietățile obiectelor din model cu ajutorul VTL.

Avantaje și dezavantaje

Fiind unul dintre cele mai cunoscute proiecte în materie de template processing, Velocity beneficiază de susținerea unei comunități bine stabilite. De asemenea, documentația de pe site-ul oficial este generoasă și există multe articole, care răspund la diverse întrebări. În plus, în decursul timpului au fost publicate câteva cărți dedicate proiectului Apache Velocity. Dacă aceste resurse nu sunt de ajuns, există un mailing list cu o arhivă bogată, la care ne putem abona.
Există o varietate de aspecte care ne pot convinge să utilizăm acest produs în următorul nostru proiect: Velocity este un procesor robust, flexibil şi bogat în funcţionalităţi. Există dezvoltatori care afirmă că acesta ar fi cel mai puternic toolde acest tip de pe piaţă.
Un alt plus al acestui proiect este faptul că, pe lângă Velocity Engine, are în componență o serie de subproiecte: Tools (unelte și elemente de infrastructură, folositoare pentru dezvoltarea de aplicații web și nu numai), Anakia (transformare de documente XML), Texen (generare de text), DocBook Framework (creare de documentație), DVSL (Declarative Velocity Style Language - transformări XML).
Când vine vorba despre suport pentru IDE-uri, Velocity beneficiază de o serie deplugin-uri dezvoltate de membri ai comunităţii. Aceste plugin-uri sunt dedicate unor IDE-uri precum Eclipse, NetBeans, IntelliJ IDEA, ca să le amintim doar pe cele mai populare. Multe dintre acestea oferă evidenţierea sintaxei şi chiarautocompletion. La dezvoltarea exemplului prezentat în acest articol am folosit Velocity Edit pentru Eclipse.
Așa cum am arătat într-un paragraf anterior, integrarea cu Spring MVC este facilă. De asemenea, distribuţia Spring MVC conţine o bibliotecă de macro-uri pentrubinding support şi form handling, unelte valoroase pentru dezvoltarea de aplicațiiweb.
Deși este cel mai popular template engine în universul Java, Apache Velocity nu a mai beneficiat de niciun release din noiembrie 2010, când s-a lansat versiunea 1.7 a nucleului proiectului. Proiectul este încă activ, însă comunitatea pare a fi mulțumită cu funcționalitățile deja implementate și încă nu există un releaseplanificat.
Velocity este un proiect la care s-a contribuit intens, devenind un produs complex, intimidant pentru noii utilizatori. Sintaxa este oarecum greoaie, iar scrierea detemplate-uri fără ajutorul unui IDE care să suporte sintaxa VTL poate fi un coşmar.

FreeMarker

FreeMarker este un produs matur, distribuit sub licenţă BSD. Asemănător proiectului Apache Velocity, FreeMarker oferă funcţionalităţi complexe care vin în întâmpinarea nevoilor dezvoltatorilor de aplicaţii web. Acesta a fost proiectat pentru generarea eficientă a paginilor HTML, însă posibilităţile utilizării tool-ului nu se opresc aici. Aşa cum afirmă creatorii proiectului, acesta este un produs software generic pentru generarea de text, aceasta însemnând orice de la HTML la cod sursă.

FreeMarker Template Language

Pentru descrierea şabloanelor, FreeMarker ne pune la dispoziţie un limbaj puternic de templating, numit FreeMarker Template Language. FTL ne permite definirea de expresii, funcţii şi macro-uri în cadrul şabloanelor pe care le scriem. De asemenea, ne este pusă la dispoziţie o bibliotecă bogată cu directive predefinite, care ne dau posibilitatea să iterăm colecţii de date, să includem alte şabloane şi multe altele. În continuare, prezentăm un exemplu de apel al unei directive FTL, care asignează o valoare unei variable:
<#assign magazineUrl = "http://www.todaysoftmag.com/">
Observăm că în limbajul de templating specific FreeMarker, directivele predefinite se apelează folosind sintaxa <#numedirectiva parametri>, iar macro-urile se apelează cu ajutorul sintaxei <@macro parametri>. Expresiile se scriu astfel:${expresie}.

Integrarea cu Spring MVC

La fel ca în cazul Apache Velocity, FreeMarker beneficiază de suport pentru integrarea cu Spring MVC chiar din partea creatorilor framework-ului web. Astfel, distribuția Spring MVC ne oferă o implementare de ViewResolver, dar şi o bibliotecă cu macro-uri pentru binding support şi form handling.
Folosind aceeași modalitate pentru a crea o aplicație Spring MVC + FreeMarker ca în cazul Apache Velocity, remarcăm că singurele modificări pe care trebuie să le efectuăm sunt în fișierul de configurare Spring și în șabloane. De fapt, vom vedea că acest lucru este valabil și atunci când ne vom ocupa de proiectele Thymeleaf și Rythm. De asemenea, trebuie să remarcăm că avem nevoie să declarăm în fișierul de configurare Maven dependința freemarker din grupul org.freemarker. Codul sursă al proiectului exemplu poate fi descărcat de la următoarea adresă:https://springfreemarker.googlecode.com/svn/trunk.
În servlet-context.xml înlocuim bean-ul de configurare și bean-ul cu rol de view resolver. Cel mai interesant aspect al acestor elemente XML este proprietatea cu cheia auto_import, care ne permite să importăm în toate fișierele noastre FTL macro-urile definite în fișierul spring.ftl, oferit de către distribuția Spring MVC. Acestea sunt accesibile prin intermediul alias-ului spring:
/spring.ftl as spring
Șablonul corepunzător view-ului list este reprezentat de fișierul list.ftl. Partea notabilă a acestuia este prezentată în continuare:
<#include "header.ftl" />

Products

<#include "footer.ftl" />
În acest template observăm cum se poate include conținutul altui șablon, cum putem itera o colecție de obiecte și cum scriem o expresie FTL.

Avantaje și dezavantaje

Proiectul FreeMarker se bucură de o documentație cuprinzătoare, site-ul oficial oferind un manual bogat, din care atât programatorii, cât și designerii pot extrage multă informație utilă. De asemenea, există un mailing list pentru discuții, însă utilizatorii sunt încurajați să ceară ajutor pe Stack Overflow, punând întrebări marcate cu tag-ul "freemarker". Deși FreeMarker este un template engine popular, până în prezent s-a publicat o singură carte dedicată acestuia.
FreeMarker oferă un limbaj de templating complet și relativ ușor de înțeles. Se poate spune că acest procesor de șabloane se bate de la egal la egal cu Velocity, fiind un produs matur, gata să fie integrat în proiecte enterprise. Merită menționat că, asemeni proiectului prezentat anterior, FreeMarker oferă mecanisme decaching al șabloanelor.
Pe pagina oficială există o listă cu o serie de plugin-uri pentru diverse medii de programare. Pentru exemplul prezentat în acest articol am folosit plugin-ul care face parte din JBoss Tools Project pentru Eclipse. Acesta oferă evidențierea sintaxei, indicatori pentru erorile de sintaxă, code completion pentru numele de macro-uri și de proprietăți ale bean-urilor. Trebuie să remarcăm că plugin-urile disponibile pentru FreeMarker nu sunt la fel de puternice precum cele scrise pentru Apache Velocity. De fapt, plugin-ul dedicat NetBeans nu pare să funcționeze pentru versiunea 7 a acestuia, deși pe site este indicat că suportă versiunile mai mari sau egale cu 6.
La fel ca în cazul Apache Velocity, FreeMarker se integrează ușor cu Spring MVC. Așa cum am văzut într-o secțiune anterioară, Spring MVC oferă atât o implementare pentru ViewResolver, cât şi o bibliotecă cu macro-uri pentru binding support şi form handling.
Proiectul este destul de activ, cea mai recentă versiune fiind 2.3.20, publicată în iunie 2013.
Am văzut că proiectul prezintă cam aceleași plusuri precum procesorul de șabloane prezentat înaintea lui și putem spune că și la capitolul minusuri se aseamănă. Fiind un proiect la care se lucrează de ani buni, a devenit complex, apărând uneori ca dificil de stăpânit pentru noii utilizatori.

Thymeleaf

Thymeleaf este o bibliotecă Java distribuită sub versiunea 2.0 a licenței Apache, având ca scop principal crearea de șabloane într-un mod elegant. Cel mai potrivituse case pentru Thymeleaf este generarea de documente XHTML / HTML5 în context web. Totuși, acest tool poate fi folosit și în medii offline, fiind capabil să proceseze documente XML.
Creatorii Thymeleaf ne oferă un modul pentru integrarea cu Spring MVC, care ne dă posibilitatea să folosim acest produs pentru stratul de vizualizare al aplicațiilor noastre web, fiind astfel un substituent pentru JSP. Thymeleaf este bazat pe seturi de trăsături numite dialecte. Distribuția standard vine cu dialectele Standard șiSpringStandard, care ne permit să creăm așa-numite natural templates. Acestea pot fi afișate corect de către browser, chiar dacă le accesăm ca fișiere statice. Astfel, aceste documente pot fi privite ca niște prototipuri. Dacă avem nevoie de alte funcționalități decât cele predefinite, Thymeleaf ne dă posibilitatea să ne creăm propriile noastre dialecte. Un dialect oferă funcționalități cum ar fi evaluarea expresiilor sau iterarea colecțiilor.
Nucleul Thymeleaf este construit în jurul unui motor de procesare DOM, care este o implementare proprie, de înaltă performanță. Cu ajutorul acestui mecanism realizează o reprezentare a șabloanelor în memorie, iar apoi efectuează procesări pe baza configurației curente și a setului de date pus la dispozițe, traversând nodurile.

Standard Dialect și SpringStandard Dialect

Aceste două dialecte au aceeași sintaxă, marea diferență între ele fiind așa-numitul expression language folosit. Dacă dialectul Standard folosește OGNL, StandardSpring are integrat Spring Expression Language. De asemenea, dialectul SpringStandard are o serie de mici adaptări pentru a utiliza mai bine anumite funcționalități oferite de Spring. Notația pe care o folosește Thymeleaf în șabloanele sale poate fi observată în exemplul următor:
Today Software Magazine
Atunci când șablonul de mai sus este procesat cu Thymeleaf, acesta evaluează expresiile reprezentate ca valori ale atributelor situate în spațiul de nume th și înlocuiește valorile atributelor clasice HTML cu rezultatul procesării.
Pentru a putea beneficia de validarea documentului, trebuie să declarăm spațiul de nume astfel:

Integrarea cu Spring MVC

Așa cum am menționat, Thymeleaf ne oferă un modul pentru integrarea cu Spring MVC, disponibil atât pentru Spring 3 cât și pentru Spring 4. Pentru a beneficia de acesta, pentru exemplul nostru am adăugat în pom.xml dependința thymeleaf-spring3 din grupul org.thymeleaf. Codul sursă al proiectului exemplu poate fi descărcat de la următoarea adresă:https://springthymeleaf.googlecode.com/svn/trunk.

Avantaje și dezavantaje

Thymeleaf este un proiect care atrage tot mai mulți utilizatori, dar și programatori care contribuie la dezvoltarea acestuia. Site-ul oficial ne oferă o varietate de resurse pentru a ne familiariza cu acest produs. Mai mult decât atât, documentația existentă ne prezintă și cum putem extinde Thymeleaf cu propriile noastre dialecte. Pe lângă aceste tutoriale, avem la dispoziție articole pe diverse teme, un forum pentru utilizatori și un tutorial interactiv. Deși la momentul scrierii acestui articol nu există cărți dedicate acestui proiect, putem găsi numeroase articole despre Thymeleaf. De asemenea, avem la dispoziție și documentațiile Javadoc pentru API-urile thymeleaf și thymeleaf-spring.
Acest procesor de șabloane vine cu o filosofie diferită față de de Velocity și FreeMarker, lucru ce se poate observa și în sintaxa dialectelor Standard și SpringStandard. Thymeleaf pune mare accent pe conceptul de natural templating, care oferă posibilitatea creării de prototipuri statice.
O dată cu lansarea versiunii 2.0 a motorului Thymeleaf, mecanismul de procesare a șabloanelor a fost înlocuit, sporind performanțele acestuia. De asemenea, există și un sistem de caching al șabloanelor.
În ce privește integrarea cu mediile de programare, există un plugin pentru Eclipse care oferă autocompletion. Din păcate, nu există suport și pentru alte IDE-uri.
Asemeni proiectelor despre care am discutat până acum, integrarea cu Spring MVC este ușor de obținut, întrucât autorii Thymeleaf au creat un modul special pentru aceasta.
Proiectul beneficiază de lansări frecvente, versiunea curentă fiind 2.12.RELEASE. Aceasta este disponibilă publicului din decembrie 2013.
Thymeleaf oferă o gamă largă de funcționalități, însă testele arată că procesarea șabloanelor este mai lentă decât în cazul unora dintre competitorii săi.

Rythm

Rythm este un procesor de șabloane pentru aplicații Java distribuit sub licență Apache, versiunea 2.0, descris de autorul său ca fiind un produs cu scop general, ușor de folosit și foarte rapid. Asemeni altor procesoare de șabloane, putem procesa cu ajutorul acestuia documente HTML, XML, scripturi SQL, cod sursă, email-uri sau orice alt text formatat. Rythm a fost inspirat din proiectul .Net Razor, datorită sintaxei sale simple și elegante.
În aceiași termeni laudativi, autorul pretinde că preocuparea numărul unu a proiectului este experiența utilizator. De la API până la sintaxa șabloanelor, produsul este caracterizat prin simplitate. De asemenea, produsul a fost proiectat astfel încât utilizarea acestuia să fie cât mai facilă pentru programatorii Java.

Sintaxa procesorului de șabloane

Rythm folosește caracterul special @ pentru a introduce toate elementele de sintaxă. Acest lucru este exemplificat în blocul de cod prezentat în continuare:
@for (product: products) {
  • @product.getName()
  • }
    Pentru a putea utiliza în template obiecte adăugate modelului de date în controller-ul Spring, trebuie să folosim următoarea notație:
    @args java.util.List products

    Integrarea cu Spring MVC

    Pentru integrarea cu Spring MVC avem la dispoziție o bibliotecă de clase third-party, disponibilă ca artefact Maven sub id-ul spring-webmvc-rythm și grupulcom.ctlok. Având această dependință în proiect, putem declara bean-urile necesare în servlet-config.xml. Una dintre proprietățile bean-ului rythmConfigurator estemode, cu ajutorul căreia putem specifica în ce mod rulăm aplicația: dev sau prod. Codul sursă al proiectului exemplu poate fi descărcat de la următoarea adresă:https://springrythm.googlecode.com/svn/trunk.

    Avantaje și dezavantaje

    Spre deosebire de Velocity și FreeMarker, Rythm procesează șabloanele, transformându-le în bytecode Java. Datorită acestui lucru, la runtime, procesarea acestora este foarte rapidă, plasând acest proiect alături de cele mai rapide procesoare de șabloane din universul Java.
    Deși nu este la fel de vastă precum a celorlalte produse prezentate, documentația proiectului este cuprinzătoare, permițându-ne să deprindem abilitățile necesare dezvoltării de aplicații web cu ajutorul Rythm Template Engine. Pe site-ul proiectului există o serie de tutoriale, atât pentru programatori, cât și pentruwebmaster-i, iar cu ajutorul instanței Fiddle dedicate putem scrie șabloane Rythm și vedea rezultatul imediat. Fiind un proiect relativ tânăr, comunitatea din jurul lui nu este încă dezvoltată.
    Rythm poate opera în două moduri: dev (development) și prod (production). Astfel, în modul dev șabloanele sunt reîncărcate de fiecare dată când sunt modificate, pentru a scurta timpul de dezvoltare; pe de altă parte, în modul prod acestea sunt încărcate o singură dată, pentru sporirea performanței.
    Unul dintre minusurile proiectului Rythm este faptul că momentan nu oferă niciunplugin pentru medii integrate de dezvoltare. Astfel, deși sintaxa acestuia este cât se poate de prietenoasă, nu avem asistență din partea IDE-ului preferat pentru scrierea șabloanelor, un aspect important pentru mulți dezvoltatori.
    Rythm permite inserarea de cod Java în cadrul unui șablon, acesta fiind unul dintre aspectele care ne-au îndemnat să renunțăm la JSP în favoarea altor procesoare de șabloane. Așadar, vedem acest lucru ca pe un minus al proiectului.

    Performanțe

    Există prea puține teste relevante pentru determinarea performanței procesoarelor de șabloane prezentate în acest articol, însă în continuare vom prezenta rezultatele unor astfel de studii. Folosind tool-ul de benchmarkingdisponibil la adresa https://github.com/greenlaw110/template-engine-benchmarks am obținut următoarele rezultate pentru 10000 de request-uri:
    • Velocity: 3.8 secunde,
    • FreeMarker: 4.8 secunde,
    • Thymeleaf: 43.2 secunde,
    • Rythm: 3 secunde.
    Un alt test (disponibil la adresa http://www.slideshare.net/jreijn/comparing-templateenginesjvm), în care Rythm nu a fost inclus, arată că Velocity și FreeMarker au avut performanțe aproape identice, în timp ce Thymeleaf a fost, din nou, printre cele mai lente procesoare.
    Astfel, Rythm pare a fi cel mai rapid template engine dintre cele despre care am discutat în acest articol, Velocity și FreeMarker își dispută locurile al doilea și al treilea, în timp ce Thymeleaf a obținut cel mai slab timp.

    Concluzii

    Deși am văzut că proiectele prezentate ne pun la dispoziție funcționalități similare, în urma acestei discuții putem trage câteva concluzii. Atât Velocity, cât și FreeMarker sunt produse consacrate, care și-au dovedit valoarea în multe proiecte de succes, oferind performanță decentă. Pe de altă parte, Thymeleaf și Rythm sunt proiecte mai tinere, care vin cu o filosofie nouă, adaptată trendurilor în dezvoltarea web. Spre exemplu, Thymeleaf excelează la capitolul naturaltemplating, în timp ce Rythm oferă o sintaxă curată, ușor de înțeles atât pentru programatori, cât și pentru webmaster-i. Putem concluziona că alegerea unuitemplate engine depinde, în primul rând, de proiectul pentru care avem nevoie de acesta, fiecare dintre procesoarele despre care am discutat meritând să fie luat în considerare.

    Integrarea datelor între sisteme cu Talend Open Studio

    (Publicat în revista Today Software Magazine, Numărul 25, Iulie 2014: http://www.todaysoftmag.ro/article/1038/integrarea-datelor-intre-sisteme-cu-talend-open-studio)

    Aşa cum menţiona Jonathan Bowen în cartea sa, „Getting Started with Talend Open Studio for Data Integration”, de îndată ce a apărut cel de-al doilea calculator, integrarea sistemelor a devenit o parte esenţială a muncii echipelor IT.

    Complexitatea sistemelor de astăzi, împreună cu ritmul alert în care afacerile evoluează, evidenţiază nevoia de a avea la îndemână un set de unelte care să ne permită executarea rapidă a sarcinilor de integrare. De asemenea, trebuie să fim în stare să reacţionăm cu promptitudine la oportunităţile de noi afaceri.

    Experienţa ne-a arătat că, de cele mai multe ori, noii clienţi vin cu cerinţa de a integra în ecosistemul acestora produsul pe care noi îl oferim. Rareori un sistem informatic funcţionează izolat, în propriul său univers. În mai multe rânduri am observat că succesul proiectului propus unui client a depins de capacitatea noastră de a integra sistemul cu produsele pe care acesta deja le folosea.

    Procesul despre care vorbim poate însemna sincronizarea a două baze de date o singură dată sau recurent, consumarea unor servicii – fie ele servicii web sau de altă natură – generarea şi transferul de fişiere în diferite formate etc. Aşadar, observăm că avem de-a face cu o varietate de modalităţi prin care putem duce la îndeplinire aceste sarcini, acest lucru contribuind la creşterea complexităţii problemei. De asemenea, uneori este la latitudinea noastră să decidem modalitatea prin care vom realiza integrarea însă, de multe ori, clientul are cerinţe specifice şi în legătură cu acest aspect.

    Atunci când ne confruntăm cu o astfel de situaţie, putem fie să construim manual interfaţa între sisteme, ca o soluţie custom, fie să utilizăm un tool specializat pe rezolvarea problemelor de integrare. Un astfel de tool este Talend Open Studio, care vine cu o ofertă interesantă pentru a ne ajuta la rezolvarea sarcinilor noastre de integrare.

    Un overview al mediului Talend Open Studio

    Talend Open Studio for Data Integration este un mediu de dezvoltare grafic care, după cum spune şi numele acestuia, este specializat în integrarea datelor între sisteme. La baza sistemului open source stă mediul Eclipse. Alături de crearea soluţiilor de integrare, Talend Open Studio cuprinde şi mecanismele necesare livrării acestora – job-urile pot fi rulate atât din interiorul mediului, cât şi ca script-uri de sine stătătoare.

    Pentru modelarea proceselor, sistemul utilizează conectori. Dezvoltatorii produsului ne oferă peste 800 de astfel de conectori, care ne dau posibilitatea să conectăm cu uşurinţă baze de date, să citim informaţii din diverse surse, să transferăm fişiere şi să efectuăm operaţii asupra lor. De asemenea, avem posibilitatea de a conecta componente specializate pentru a defini procese complexe de integrare.

    O bună parte din munca pe care o îndeplinim cu ajutorul Talend Open Studio este reprezentată de modelarea grafică a proceselor pe care dorim să le definim. În tot acest timp, platforma îşi face treaba de zidar în background, generând cod Java. În fond, fiecare componentă pe care o utilizăm are asociat un comportament, descris prin intermediul codului Java.

    Având în vedere faptul că acesta este un tool grafic, produsul poate fi utilizat atât de programatori, cât şi de persoane care nu au cunoştinţe de programare. Totuşi, pentru a putea defini anumite comportamente complexe, este nevoie să scriem din când în când cod Java, lucru care ne determină să concluzionăm că utilizatorii care nu cunosc programare se confruntă cu anumite limitări.

    Talend Open Studio este relativ uşor de folosit, este o modalitate rapidă de a modela scenarii de integrare, de cele mai multe ori reducând timpul de implementare de la săptămâni sau luni, la zile sau chiar ore, în funcţie de complexitatea proiectului. Totuşi, trebuie să avertizăm cititorii că, asemeni multor altor domenii, dacă din cauza excesului de zel sau a unui design nepotrivit facem overengineering, riscăm să obţinem o soluţie complexă, greu de înţeles pentru alţi utilizatori sau chiar ineficientă. Există şi aici necesitatea respectării unor bune practici, care să asigure calitatea soluţiei noastre.

    Printre alte beneficii ale utilizării Talend Open Studio, trebuie să remarcăm că acesta este un produs open source, care permite utilizatorilor să extindă platforma după nevoie. De asemenea, utilizându-l creşte productivitatea, deoarece dezvoltatorii se pot concentra mai mult la definirea procesului decât la implementarea tehnică a acestuia. Ne sunt puse la dispoziţie o mulţime de componente, potrivite situaţiilor mai mult sau mai puţin obişnuite, cu care putem opera pentru a ne defini procesele. În plus, comunitatea utilizatorilor Talend este activă şi gata să ofere sfaturi tehnice.

    Scenarii de utilizare

    După cum am menționat în secțiunea anterioară, cele mai obișnuite scenarii de utilizare a proiectului Talend Open Studio sunt următoarele:

    Transfer între baze de date: Atunci când sunt create sisteme noi sau cele existente sunt actualizate, este nevoie ca datele să fie migrate într-o nouă bază de date. Aceasta poate să aibă aceeași schemă sau una diferită, iar Talend Open Studio ne oferă conectorii și acțiunile necesare acestui proces.

    Schimb de fișiere: Sarcinile de integrare pot necesita transferuri de date în cantități mari. Acest lucru se realizează adesea prin intermediul fișierelor. Un exemplu de astfel de fișier este clasicul CSV (comma separated values). De asemenea, este posibil ca sistemul care primește fișierul de transfer să aibă nevoie de date într-un alt format. Și acest caz este acoperit de către Studio, fiindcă ne dă posibilitatea să definim procese care efectuează transformări asupra datelor transferate. În plus, avem la dispoziție capabilități de management al fișierelor, prin operații cum ar fi transferul prin FTP sau arhivarea.

    Sincronizare: Sistemele care colaborează nu sunt conectate întotdeauna la același data repository, ceea ce înseamnă că anumite informații pot fi duplicate într-un ecosistem. În consecință, avem nevoie să ne asigurăm că acestea sunt sincronizate periodic. Acesta este cazul datelor despre clienții unei companii, care pot fi prezente, spre exemplu, în sistemul de finanțe, cel de distribuție sau în platforma CRM. Talend Open Studio poate fi folosit pentru a realiza sincronizarea sistemelor, cu ajutorul unor job-uri care automatizează procesul.

    ETL: Acesta este un acronim pentru Extract, Transform, Load, termeni care descriu un proces de bază pentru sistemele data warehouse. Un astfel de proces extrage date din sisteme operaționale, le transformă aplicând reguli sau funcții, iar apoi le încarcă în data warehouse. Din nou, Talend Open Studio ne face viaţa mai uşoară, ajutându-ne substanţial la implementarea acestui tip de proces.

    Exemplu

    Pentru a ilustra uşurinţa utilizării acestei platforme, creăm un proiect cu un job care transformă un fişier XML într-un fişier CSV. Modelul grafic pentru acest job simplu este ilustrat în figura de mai jos.


    În partea stângă avem o componentă de tip tFileInputXML, iar în partea dreaptă o componentă de tip tFileOutputDelimited. Acestea sunt conectate printr-un conector Main. Înainte de a trage componenta de intrare în designer am definit un obiect metadata, căruia i-am asociat un fișier XML. Studio-ul a detectat automat schema documentului și ne-a dat posibilitatea să selectăm ce noduri să fie transferate către output. Prin intermediul conectorului Main, Talend a transferat către fișierul de ieșire exact structura pe care am definit-o, fără ca noi să scriem vreo linie de cod. Tot ce a trebuit să configurăm în componenta de ieșire a fost calea și numele fișierului CSV.
    Bineînțeles, putem extinde acest job, conectând în continuare alte componente, cum ar fi cele care lucrează cu conexiuni FTP, pentru a transfera fișierul nostru către sistemul țintă.

    Concluzii


    În secțiunile anterioare am văzut pe scurt care este contextul în care sunt realizate procesele de integrare, ce este Talend Open Studio și care sunt beneficiile utilizării acestui produs. De asemenea, printr-un mic exemplu am încercat să ilustrăm simplitatea utilizării Studio-ului, rapiditatea implementării job-urilor și să ne facem o părere despre capacitatea acestei platforme.

    Atlassian JIRA REST API

    (Publicat în revista Today Software Magazine, Numărul 30, Decembrie 2014: http://www.todaysoftmag.ro/article/1186/atlassian-jira-rest-api)

    Nu cred că este o coincidenţă faptul că Atlassian JIRA este tool-ul folosit pentruissue tracking în toate proiectele la care am luat parte până acum. Deşi există destul de multe produse de genul acesta pe piaţă, JIRA este unul dintre numele recunoscute de majoritatea actorilor implicaţi în proiecte informatice. Alături de alte titluri sonore precum Bugzilla sau Redmine, JIRA iese în evidenţă prin setul complet de funcţionalităţi, calitate, uşurinţa utilizării, dar şi prin extensibilitatea sa.
    Atlassian JIRA a fost conceput ca un produs flexibil, uşor extensibil prin intermediul plugin-urilor. De asemenea, sistemul comunică cu lumea exterioară printr-o interfaţă REST, prin intermediul căreia clienţii platformei pot efectua diverse operaţii. În rândurile care urmează ne vom concentra atenţia asupra trăsăturilor acestui API, discutând câteva use case-uri clasice, cum ar fi căutarea unui issue sau adăugarea unui comentariu. De asemenea, vom petrece puţin timp uitându-ne atât la clientul Java pus la dispoziţie de Atlassian, cât şi la implementarea unui client REST utilizând Jersey, implementarea de referinţă de la Oracle.

    JIRA REST Java Client

    Atlassian ne pune la dispoziţie o bibliotecă de clase menită să ne înlesnească lucrul cu API-ul REST, aceasta numindu-se sugestiv JIRA REST Java Client. Această bibliotecă expune la rândul său un API aproape complet pentru operațiile pe care le putem face într-un proiect JIRA. Spre exemplu, prin intermediul acestui client avem posibilitatea să găsim un anume proiect după cheie, să creăm tichete, să le ştergem, să adăugăm atașamente, să adăugăm worklog-uri și multe altele.
    Metodele pe care le avem la dispoziție sunt grupate în mai multe clase, în funcție de obiectul business despre care este vorba. De exemplu, putem apela metodele ce țin de administrarea issue-urilor doar după ce obținem un obiect de tip IssueRestClient. Înainte de aceasta, avem nevoie de un obiect de tip JiraRestClient, creat prin intermediul unei implementări asincrone a interfeței JiraRestClientFactory.
    Detaliile menționate mai sus pot fi observate în clasa JiraClient care face parte din proiectul demonstrativ ce însoțește acest articol. Proiectul poate fi descărcat de la adresa menționată în secțiunea Resurse. Trebuie să observăm faptul că acest proiect Java are scop didactic, codul sursă fiind unul minimal, care nu urmăreşte să respecte bunele practici.
    Să presupunem că dorim să obținem cu ajutorul bibliotecii JRJC un obiect de tip Issue, ce modelează detaliile unui tichet JIRA. Acum că avem la dispoziție un obiect de tip JiraRestClient putem scrie următoarele:

    Promise promise = jiraRestClient.getIssueClient().getIssue("JRA-9");
    Issue issue = promise.claim();

    Observăm că metoda getIssue(String issueKey) returnează un obiect de tip Promise, motiv pentru care, pentru a obține instanța Issue trebuie să apelăm metoda claim(). În aceeași manieră trebuie să procedăm și pentru obținerea altor obiecte, cum ar fi proiecte, worklogs etc. .
    Unul dintre avantajele utilizării acestei biblioteci îl reprezintă faptul că nu trebuie să ne preocupăm de subtilitățile lucrului cu servicii REST. În fond, până în acest moment pentru noi a fost transparent faptul că avem de-a face cu un API REST. Pentru a ne face o părere mai clară despre ce înseamnă JIRA REST API, trebuie să realizăm propria noastră implementare a unui client REST, lucru pe care îl vom face utilizând Jersey.

    Client REST cu Jersey

    Jersey ne oferă un mod simplu și rapid de a crea un client REST, aspect pe care îl ilustrăm în continuare:

    String auth = new String(Base64.encode(USERNAME + ":" + PASSWORD));
    Client client = Client.create();
    WebResource webResource = client.resource(JIRA_SERVER + REST_PATH + query);
    Builder builder = webResource.header("Authorization", "Basic " + auth)
        .type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);

    Revenind la scenariul în care dorim să regăsim un tichet pe baza cheii, presupunem că parametrul query conține o cale de genul issue/JRA-9, unde JRA-9este cheia tichetului. Pentru a obține obiectul Issue apelăm metoda get(), care corespunde metodei HTTP GET.

    ClientResponse clientResponse = builder.get(ClientResponse.class);

    În acest moment putem obține obiectul JSON serializat, sub forma unui String:

    String json = clientResponse.getEntity(String.class);

    Acest String poate fi apoi deserializat într-un bean creat de noi cu ajutorul bibliotecii Jackson, care ne pune la dispoziție diverse unelte de lucru cu JSON. Acest scenariu este unul dintre cele mai simple, însă lucrurile devin mai complicate atunci când trebuie să creăm un worklog, spre exemplu. În acest caz, mai întâi trebuie să creăm un bean cu ajutorul căruia să modelăm un worklog și să populăm o instanță cu informațiile pe care dorim să le salvăm. Apoi trebuie să serializăm acest obiect sub forma unui String și să-l transmitem serviciului REST după modelul de mai sus, însă folosind metoda HTTP POST de data aceasta. Răspunsul serviciului va conține obiectul salvat sub formă serializată, îmbogățit cu noi informații, cum ar fi id-ul worklog-ului.

    Concluzii

    JIRA REST API este o interfață către lumea exterioară care are o valoare business incontestabilă. Acest API oferă organizațiilor posibilitatea să integreze cu ușurință tool-ul în ecosistemul propriu, pentru a defini procese dintre cele mai creative și complexe. Totuși, se poate observa că JIRA REST API nu acoperă în totalitate scenariile de utilizare JIRA. Unul dintre aspectele pentru care utilizatorii așteaptă o rezolvare îl reprezintă imposibilitatea de a lucra cu filtrele salvate. Există și un tichet pe acest subiect (JRA-36045), care încă este deschis.
    Pe de altă parte, trebuie să menționăm că API-ul REST vine cu funcționalități importante, cum ar fi posibilitatea de a regăsi câmpurile custom și valorile acestora, operație pe care nu o puteam face cu API-ul SOAP.
    JIRA REST API a ajuns la versiunea a doua şi, chiar dacă există loc de îmbunătăţiri, putem spune că este un produs matur, care vine cu funcţionalităţi importante față de predecesorul său.

    Resurse

    1. https://jira-rest-client-ro-leje.googlecode.com/svn/trunk
    2. https://docs.atlassian.com/jira/REST/latest/
    3. http://www.j-tricks.com/tutorials/java-rest-client-for-jira-using-jersey
    4. http://www.baeldung.com/jackson-ignore-null-fields

    Internet of Things în universul Java

    (Publicat în revista Today Software Magazine, Numărul 31, Ianuarie 2015: http://www.todaysoftmag.ro/article/1244/internet-of-things-in-universul-java)

    Experții din domeniul IT au numit 2014 "anul Internet of Things ", acesta fiind unul dintre cele mai fierbinți subiecte ale anului care tocmai s-a încheiat. Titlul atribuit nu este deloc surprinzător dacă luăm în considerare faptul că site-uri importante precum dzone.comjaxenter.com sau oracle.com au publicat câteva articole pe săptămână despre tehnologiile din sfera Internet of Things, iar blogger-ii nu au scăpat nicio ocazie să posteze despre ultimele lor proiecte IoT. Nici editurile nu au fost mai prejos, în 2014 fiind publicate zeci de titluri, multe altele așteptând să vadă lumina tiparului anul acesta.
    Toate acestea s-au întâmplat în contextul lansării unei multitudini de noi gadgeturi sau dispozitive inteligente, dar și a numeroase platforme software sau implementări ale unor protocoale mai mult sau mai puțin cunoscute. Mulți împătimiți ai tehnologiei au auzit de produse populare, lansate în ultimii ani, precum Philips Hue sau Nest, însă începând cu 2014 e nevoie de un efort activ să putem ține pasul cu frecvența apariției de noi dispozitive, cum ar fi Sen.se Mother, Fitbit Charge sau SkyBell. IoT influențează din ce în ce mai mult domeniile din viața de zi cu zi, precum sănătatea cu dispozitive care monitorizează pacienții, îngrijire la domiciliu, prin gadgeturi pentru un stil de viață sănătos, transporturi, cu autovehicule conectate, automatizarea locuințelor, industrie etc. .
    Înainte de a discuta despre modalitățile prin care comunitatea Java își poate face auzită vocea în sfera Internet of Things, suntem datori să descriem pe scurt ce înseamnă mai exact IoT.

    Definiții

    Internet of Things sau, pe scurt, IoT este un concept dezbătut din ce în ce mai mult în ultimii ani, dar semnificația sintagmei nu este întotdeauna pe deplin înțeleasă. CASAGRAS (Coordination and support action for global RFID-related activities and standardisation) ne dă o definiție destul de abstractă, care spune despre IoT următoarele: este "o infrastructură de rețea globală, care conectează obiectele fizice și virtuale prin intermediul exploatării capturii de date și a capacității de comunicare. Această infrastructură include dezvoltările existente și viitoare ale rețelelor și ale Internet-ului. Aceasta va pune la dispoziție modalități de identificare a obiectelor, senzori și capacitatea de conectare ca bază pentru dezvoltarea de servicii sau aplicații independente și cooperante. Acestea vor fi caracterizate printr-un grad înalt de autonomie pentru captura de date, transferul evenimentelor, conectivitatea în rețea și interoperabilitate" [1].
    Definiția oferită de Stephen Haller de la SAP Research ne ajută să ne creăm o imagine mai concretă asupra Internet of Things, despre care spune că este "o lume unde obiectele fizice sunt integrate omogen în rețeaua informațională și unde aceste obiecte fizice pot deveni participanți activi în procesele business. Serviciile sunt gata să interacționeze cu aceste obiecte inteligente prin intermediul Internet-ului, să interogheze și să-și schimbe starea și orice informație asociată cu ele, luând în considerare securitatea și chestiunile ce țin de intimitate"[2].
    O altă explicație este dată de Oracle, care afirmă că "Internet of Things se referă la colectarea și gestionarea cantităților masive de date provenite de la rețelele - aflate într-o rapidă expansiune - de dispozitive și senzori, procesarea acestor date și apoi partajarea lor cu alte obiecte conectate"[3]. Pentru a ne da seama care este ordinul de mărime al acestor cantități de date, ne putem uita la exemplul echipei de navigație Oracle Team USA, care lucrează cu ambarcațiuni echipate fiecare cu câte 300 de senzori, meniți să furnizeze informații despre o mulțime de parametri, cum ar fi eficacitatea reglajelor pânzelor, tăria și stabilitatea carenei sau tensiunea din catarg. Acești senzori măsoară 3000 de variabile de 10 ori pe secundă, producând 500 GB de date neprelucrate pe zi. Un alt aspect interesant este faptul că în prezent doar 11% din volumul total de date este generat de dispozitive, dar IDC estimează că până în 2020 procentul va crește la 40%[4].
    Acest titlu descriptiv, care încearcă să surprindă esența următorului mare trend în IT, reprezintă în principiu efortul de a regândi relația noastră cu obiectele pe care le folosim în fiecare zi, dar și a obiectelor între ele. Conform experților, IT-ul se va îndrepta puternic în această direcție. Ca dovadă, mai multe nume sonore ale tehnologiei secolului al XXI-lea, precum Cisco sau Bosch, au întreprins studii pe această temă, ajungând la concluzia că proiectele din sfera IoT vor depăși valoarea economică de 15 trilioane de dolari, până în 2020[5]. De asemenea, analiștii de la Cisco afirmă că în 2010 existau peste 12.5 miliarde de obiecte conectate la Internet și estimează că vor exista aproximativ 25 miliarde de "lucruri" inteligente, conectate la Internet, până la finalul anului 2015. Pentru anul 2020, previziunea lor este de 50 de miliarde de "lucruri"[6].

    Oracle și Java Embedded

    În acest context intră în scenă Java, atât ca platformă ce are la bază Java Virtual Machine, cât și ca limbaj de programare, cu o comunitate de peste 9 milioane de utilizatori. Facem această distincție între platformă și limbaj[7] întrucât un dispozitiv care rulează JVM nu este limitat la execuția de aplicații Java; acestea pot fi, în anumite condiții, aplicații scrise cu ajutorul Scala, Clojure etc. . În trecut, programarea dispozitivelor embedded se făcea preponderent în limbaje de nivel scăzut, precum C sau limbaj de asamblare.
    În acest articol vom încerca să ne facem o părere despre soluțiile propuse de Oracle pentru IoT, companie a cărei implementare a platformei Java se bucură de cea mai mare popularitate printre programatori. Totuși, în articolele viitoare vom privi mai îndeaproape și caracteristicile altor proiecte Java pentru IoT, cum ar fi cele din stiva dezvoltată de Eclipse Foundation.
    În ultimii ani, Oracle a investit masiv într-o linie de produse denumite sugestiv Java Embedded, lucru ce oferă posibilitatea programatorilor Java să scrie aplicații pentru astfel de dispozitive, de la smart card-uri și module wireless, până la single board computer-e (SBC), cum ar fi Raspberry PI. Platformele Java Embedded sunt principalul lucru pe care Oracle îl oferă dezvoltatorilor embedded și prin intermediul căruia contribuie la influența pe care o are Java în sfera Internet of Things.
    Viziunea Oracle pentru Java 8 a fost să lanseze, pe lângă Standard Edition (SE), încă două variante importante ale platformei, mai exact Oracle Java ME Embedded 8 și Oracle Java SE Embedded 8, la care se adaugă Java Embedded Suite. Henrik Ståhl, vicepreședinte peste product management pentru Java și IoT la Oracle, afirmă în ediția noiembrie/decembrie 2014 a revistei Oracle Java Magazine că, prin lansarea acestor variante ale platformei au "făcut disponibile pe platforme embedded, care au doar câteva sute de KB de memorie, feature-urile cu care programatorii sunt obișnuiți în Java SE"[8].


    Fig. 1 Privire de ansamblu asupra platformei Oracle Java ME Embedded 8[9]

    Prin lansarea noii versiuni a distribuțiilor amintite mai sus, Oracle a încercat să le aducă la un grad cât mai înalt de compatibilitate una cu cealaltă și, în același timp, să le alinieze la Java SE 8. Pentru aceasta, s-a introdus conceptul de Compact Profiles, dezvoltatorii putând alege între setul complet de API-uri Java SE și alte trei subseturi care au la dispoziție doar acele API-uri care sunt necesare pentru use case-urile relevante. Un astfel de use case poate fi rularea unei stive OSGi (Open Service Gateway initiative). Așa cum vom vedea într-un articol viitor, OSGi joacă un rol important în cadrul eforturilor făcute de Eclipse Foundation pentru implementarea unei stive complete IoT, numită Open IoT Stack for Java.
    Începând cu Java 8, versiune lansată în prima parte a anului 2014, am văzut că Oracle face eforturi considerabile pentru a aduce la zi varianta Micro Edition (ME) a platformei, lucru ce confirmă implicarea corporației în războiul soluțiilor IoT. Printre îmbunătățirile aduse platformei se numără eficientizarea procesului dedeployment pe dispozitive de dimensiuni mici, cum ar fi senzorii inteligenți saugateway-urile embedded. De asemenea, API-urile au fost actualizate pentru a răspunde nevoilor de programare a dispozitivelor țintă. Prin această nouă versiune Java ME, platforma are mult mai multe lucruri în comun cu Java SE, însă funcționalități precum reflection sau expresiile lambda urmează să fie adăugate. Acest aspect este important, întrucât în felul acesta, orice programator Java se va putea implica în proiecte embedded într-un timp scurt, fără a face eforturi considerabile. În 2015, Henrik Ståhl anunță că unii producători de hardwareplănuiesc să integreze Java ME în dispozitivele lor, ceea ce va conduce la o mai mare rată de adopție a platformei.
    Componentele construite cu soluțiile embedded despre care discutăm, livrate într-un context IoT, dau acces aplicațiilor business la resursele instalate în mediul înconjurător, atât pentru a primi input de la acestea cât și pentru a lansa comenzi. Un astfel de use case este orchestrarea sistemelor eterogene de control a temperaturii și a iluminării într-o clădire. Observăm că abilitatea Java ME de a controla echipamente cum ar fi senzori, valve sau servo-motoare, reprezintă unul dintre aspectele fundamentale ale obținerii unei infrastructuri IoT.
    Privind lucrurile de la o oarecare distanță, putem observa că arhitectura Java ne permite să creăm aplicații pe verticală, după cum a arătat și Maulin Patel, liderul în soluții de procesare embedded de la Freescale[8]. Întâi colectăm datele de la obiectele inteligente cu Java ME, apoi trecem la Java SE pentru servicii de gateway, iar în final executăm gestiunea și procesarea datelor cu Java EE, în cloud.
    Aproape de fiecare dată când se vorbește despre IoT, se aduce în discuție problema securității. Într-un mediu eterogen și deschis precum este o infrastructură Internet of Things, securitatea este esențială, dar greu de obținut. Este de ajuns ca un atacator să aibă acces la una dintre componentele soluției IoT pentru a fi capabil să exploateze posibilele breșe în sistemul defensiv al acesteia. Spre exemplu, în cazul contoarelor inteligente de utilități, cel mai interesat de compromiterea acestor unități poate fi chiar proprietarul locuinței în care au fost instalate. Astfel, potențialul atacator are chiar și acces fizic la echipament, lucru ce ridică întrebări cu privire la nivelele la care trebuie implementate mecanisme de securitate. Acum că am remarcat seriozitatea acestei chestiuni, putem veni cu o veste bună pentru dezvoltatorii IoT din universul Java, întrucât această platformă asigură securitatea datelor pe întreaga verticalitate a sistemului implementat. Securitatea este o caracteristică înglobată în arhitectura platformei, fiind dezvoltată și actualizată constant, cu fiecare nouă versiune. Vom reveni cu detalii referitoare la securitatea oferită de Java ME 8 într-unul dintre paragrafele următoare, când vom discuta câteva caracteristici tehnice ale platformei.

    Java ME Embedded 8

    Platforma dedicată dispozitivelor cu cele mai puține resurse, cum ar fi cardurile, se numește sugestiv, Java Card. Totuși, primul produs din familia Oracle care aduce cu adevărat o contribuție importantă în spațiul IoT este Java ME Embedded 8. Prin urmare, în continuare ne vom concentra atenția asupra acestuia. Înainte de a ne uita la câteva detalii, trebuie să menționăm Java ME Embedded constă din două versiuni: Java ME Embedded și Java ME Embedded Client.
    Java ME Embedded 8 este o platformă ce poate fi folosită de către dispozitive care au mai puțin de 1 MB de memorie. Astfel, este potrivită pentru "obiecte inteligente" fără interfață grafică, care au timp îndelungat de funcționare și resurse limitate.
    Așa cum putem vedea în Figura 1, la baza Java ME Embedded 8 stă mașina virtuală, pe care o găsim sub denumirea Connected Limited Device Configuration sau, pe scurt, CLDC 8. Această componentă reprezintă un sub-set al Java SE 8, dedicat dispozitivelor embedded. După cum am menționat mai sus, o dată cu versiunea 8, CLDC reprezintă un prim pas spre o mai bună aliniere cu Java Standard Edition și totodată un important salt de la CLDC 1.1.1. Așadar, avem la dispoziție adnotații,generics și multe alte caracteristici Java, familiare tuturor dezvoltatorilor. Deși s-a realizat o evoluție foarte importantă prin lansarea CLDC 8, s-a reușit menținerea compatibilității binarelor cu versiunea anterioară.
    Deasupra fundației pe care o reprezintă CLDC 8 stau mai multe componente definitorii pentru platformă. Una dintre ele este Generic Connection Framework 8(GCF 8). Așa cum se poate intui, această componentă gestionează problemele de conectivitate. Acest framework este necesar întrucât în spațiul embeddedposibilitățile de conectare sunt multiple, iar dispozitivele pe care rulează aplicația noastră au interfețe variate de comunicare cu lumea exterioară. Unele pot avea capacitate de conectare prin Wi-Fi, altele de tip cellular, Bluetooth sau prin cablu. De asemenea, pentru un control optimizat al conectivității GCF 8 expune AccessPoint API. Totodată, GCF 8 vine cu suport pentru IPv6, scăpând dezvoltatorii Java ME Embedded 8 de emoțiile epuizării adreselor IPv4.
    Revenind la subiectul securității în lumea Internet of Things, putem da câteva detalii despre modul în care GCF 8 rezolvă această problemă. Java ME Embedded 8 vine echipat cu implementări ale celor mai noi standarde în materie de securitate, printre care se numără Transport Layer Security 1.2 și Datagram Transport Layer Security 1.2. Astfel, Oracle îi asigură pe utilizatorii platformei de faptul că aceasta oferă "cele mai înalte nivele de criptare la nivel de rețea și autentificare" [9].
    Un alt bloc constructiv al Java ME 8 este Micro Edition Embedded Profile 8 (MEEP 8). Această componentă este responsabilă cu definirea modelului, a containerului în care rulează aplicația, în general cu ciclul de viață al acesteia. Prin intermediul MEEP 8 putem partaja cod între aplicații, putem actualiza componente în sistem sau aplica patch-uri aplicației. Partajarea bibliotecilor - denumite sugestiv, LIBlets - se face tot prin intermediul MEEP 8, contribuind la minimizarea necesarului de memorie și la modularizarea aplicațiilor. În plus, MEEP 8 oferă aplicațiilor posibilitatea de a comunica între ele atât sincron (Inter-MIDlet Communication sau IMC), cât și asincron, printr-un sistem de mesagerie bazat pe evenimente.
    Securitatea este un subiect important și pentru MEEP 8, deoarece se pot defini politici de securitate pentru autentificare și autorizare, în funcție de situația specifică. Astfel, încărcarea codului și execuția lui se realizează într-un mediu securizat, întrucât fiecare componentă este asociată unui client, având permisiuni specifice. Acestea trebuie verificate la fiecare încercare de acces.
    O componentă de o importanță crucială pentru Java ME Embedded 8 este Device Access API, care oferă aplicațiilor acces la dispozitive periferice, cum ar fi senzori, comutatoare sau LED-uri. Această componentă exista și în versiunile anterioare, însă acum vine cu funcționalități noi, printre care late binding, care permite adăugarea de noi periferice, fără a fi necesară modificarea API-ului.
    Alături de aceste blocuri constructive, Java ME Embedded 8 vine cu o multitudine de API-uri, precum cel pentru servicii web sau localizare.
    Având toate aceste componente Java ME Embedded la dispoziție, este la îndemâna noastră, a dezvoltatorilor, să construim aplicații embedded, contribuind la spațiulInternet of Things.
    În ajutorul nostru vine Java ME SDK 8, un toolkit complet creat pentru a întâmpina orice nevoie avem în procesul creării și întreținerii unei aplicații. Acest SDK oferă inclusiv un mediu de emulare, având posibilitatea să ne testăm aplicațiile chiar dacă dispozitivele pe care vor fi distribuite nu sunt disponibile în timpul dezvoltării. De asemenea, putem face debugging atât în modul de emulare, cât și atunci când aplicația rulează pe dispozitiv. Pentru a întregi acest set de unelte, Oracle oferă plugin-uri pentru Netbeans IDE și Eclipse IDE, care încorporează toate funcționalitățile SDK-ului. Vom discuta mai multe detalii și vom exemplifica modul de utilizare al Java ME SDK 8 într-unul dintre articolele viitoare.
    Java ME Embedded Client este o implementare CDC (Connected Device Configuration) care, în principiu, este configurația destinată dispozitivelor mobile cu ceva mai multe resurse, cum ar fi smartphone-urile. Pentru Java ME Embedded Client, această configurație a fost restrânsă și optimizată, pentru a se potrivi sistemelor embedded de categorie joasă înspre medie. Deși amprenta acestei configurații este redusă, oferă mare parte din limbajul Java. Astfel, Java ME Embedded Client este destinată obiectelor inteligente cu mai puțin de 10 MB de memorie și fără interfață grafică.

    Concluzii

    Industria IT autohtonă nu este străină de spațiul Internet of Things, începând să fie lansate produse Made in Romania, precum Pocketo sau Tintag. De asemenea, există companii în România, implicate în proiecte care se integrează în paradigma IoT. De exemplu, regăsim astfel de proiecte la Brașov în domeniul automotive, cu al său concept de connected car . Un alt lucru îmbucurător este faptul că au început să se organizeze evenimente despre IoT, unul dintre acestea fiind ALT Festival, care a avut loc în noiembrie 2014, la Brașov.
    Un obiectiv important pentru Oracle în ultima perioadă este afirmarea platformei Java în lupta care se dă între soluțiile IoT. Mai mult decât atât, corporația și-a exprimat dorința de a câștiga această bătălie, astfel încât Java să devină alegerea majorității specialiștilor implicați în astfel de proiecte. Totuși, răspunsul a venit rapid din partea oponenților, existând multe voci care și-au exprimat scepticismul cu privire la potrivirea platformei în sfera IoT. Există multe argumente, atât pro, cât și contra acestei idei, însă un lucru e cert: Java a străbătut un drum lung pentru a ajunge la gradul actual de maturitate, diversitate și aplicabilitate. Eforturile din ultimii ani au dat naștere unei noi familii de produse, care se dovedesc promițătoare și, mai mult, încep să-și dovedească valoarea în cadrul proiectelor reale IoT. Vom vedea clar acest lucru în articolul viitor, când vom atinge, prin exemple concrete, partea practică a platformei Java ME Embedded 8.

    Resurse

    [1] CASAGRAS, RFID and the Inclusive Model for the Internet of Things
    [2] Stephen Haller, Internet of Things: An Integral Part of the Future Internet, SAP Research, 2009
    [3] "The Internet of Things: Manage the Complexity, Seize the Opportunity", Oracle Corporation, 2014
    [4] IDC Digital Universe Study, sponsored by EMC, December 2012
    [5] Dzone Research, 2014 Guide to Internet of Things
    [7] Benjamin Evans, Martijn Verburg, The Well-Grounded Java Developer, Manning, 2013
    [8] "Java Development for the Internet of Things", Oracle Java Magazine, November/December 2014 Issue

    Friday, November 14, 2014

    Eclipse SWT: Cum se poate seta poziția caracterului "caret" într-un widget Text

    Astăzi lucram cu un widget Text (org.eclipse.swt.widgets.Text) și am avut nevoie să setez manual poziția caret-ului după un apel al metodei setText().
    Am descoperit în Javadoc metoda getCaretPosition(), care returnează un int, însă API-ul nu oferă și o metodă setCaretPosition().
    Căutând pe Internet soluții la problema mea, am găsit post-uri despre cum se poate muta caret-ul la sfârșitul textului, folosind metoda setSelection(int start):

    textWidget.setSelection(textWidget.getText().length());

    unde textWidget este o instanță a clasei Text. Pentru mai multe detalii, vezi post-ul de pe StackOverflow.
    De asemenea, API-ul ofera o variantă overloaded a metodei setSelection(int start), sub forma setSelection(int start, int end), indecșii start și end corespunzând poziției caret-ului.
    Astfel, am scris următoarea soluție:

    int caretPosition = textWidget.getCaretPosition();
    textWidget.setText( newValue );
    textWidget.setSelection( caretPosition, caretPosition );

    Prin acest truc am setat poziția caret-ului la valoarea anterioară apelului metodei setText(), stabilind o selecție vidă.
    Încă nu mi-e clar dacă simplul fapt că am fost nevoit să resetez manual poziția caret-ului indică un design defectuos sau nu, dar sper să revin cu un răspuns.