joi, decembrie 13, 2012

DEVOPS


Devops este o miscare care incearca sa lege doua domenii distincte: dezvoltare si operational poate nu neaparat prin intarirea colabrarii intre cele 2 departamente ci prin extinderea atributiior echipei de dezvoltare si in domeniul operational.


Acesta se inscrie in trendul actual in care dezvoltatorii pot sa ii inlociasca aproape total pe toti ceilalti oameni din firma (eu sincer nu as angaja intr-o firma decat dezvoltatori experimentati):

  • managerii de proiect - prin metodologii agile in care echipa este self managed, rolul de managementului de proiect dispare; desigur ramane high management-ul
  • testeri  - prin teste functionale automate se acopera o data pentru totdeauna testarea aplicatiei; daca apare un bug se fixeaza si se face un test automat care sa semnaleze regresia; este nevoie de testeri doar pentru ca acestea sa faca doar teste exploratorii
  • analistii de business - prin teste de acceptanta automate (executable specifications) dezvoltatorii pot sa interactioneze singuri cu clientii sa scrie specificatiile in cod :)
  • operational - oamenii care se ocupa de environmente, infrastructura si mentinerea aplicatii in productie pot fi inlociti cu scripturi automate de build, deploy, instalare de environmnets, etc

Automizarea (Automation - let the computer doing the repetitive stuff, you can do the interesting part) este cuvantul de baza. Automatizarea testelor (unitare, de integrare, functionale), build-ului, deployment-ului (in dev, test, prod), etc. aduce cu sine cateva aspecte foarte interesante:
  • spre deosebire de executarea manuala de catre o persoana a unui numar de pasi, un script automat trebuie facut o data si se executa de nenumarate ori
  • calculatorul nu poate face erori (omul este predispus la greseli)
  • daca apar erori inseamna ca ceva a fost schimbat intre timp si se poate afla din log-uri ce, se fixeaza si data viitoare nu se va mai intampla

Cateva cazuri de automatizare

  • Build (ant, maven, gradle) - procesul prin care se obtine un binar deployabil (sau chiar se deployaza) din surse
  • Continous integration - prin folosirea unui server de integrare se garanteaza ca pe trunk avem o versiune stabila si integrata a aplicatiei gata de a fi deployata
  • Automatic deployment - procesul de deployment este automatizat (cloud: cloudfoundry, amazon beanstalk, virtualization: - vmware)
  • Continous delivery - permite ca prin apasarea unui buton sa obtinem o versiune noua in productie sau pe unul din environmente (cateva minute); exemplu: update de pe SVN, build and make war (compile, execute unit tests, packaging), upload on cloud, deploy, verify with smoke tests, execute automate acceptance (eventual rollback automat)
  • Deployment pipeline (cel mai inalt nivel) -  folosind tool-uri ca Go, Jenkins (plgin in sine sau posibilitatile de a face trigger de job din alt job) se creaza un proces prin care printr-un singur commit in SVN se executa testele unitare, se face build, se deployaza pe un mediu de staging, se executa testele functionale automate; urmeaza ca un operator uman sa face teste exploratorii si oricand sa decida ca un release candidate poate fi pus in productie

Environments reprezinta masini fizice (diverse OS-uri: Windows, Linux), masini virtuale (VMWARE, EC2) sau simple servere de aplicatii (sau mai simpu aplicatii deployate in acelasi server de aplciatii). Edeea de baza este aceea de a migra aplicatia dn mediul de dezvoltare spre cel de productie incercand sa aducem in productie o aplicatie cat mai stabila cu putinta. Cateva tipuri de enironmente (fiecare firma foloseste propria denumire si semantica): dezvolate (DEV - masina fiecarui dezvoltator, DREF, DINT - integrarea dev), testare(TEST, T1, UAT - user acceptance testings, STAGING - pre-production), productie (PRODUCTION). De la stanga la dreapta este trecerea din dezvoltare spre productie trecand prin testare. Test si production trebuie sa fie foarte asemanatoare (spre exemplu clusterizate in acelasi mod, acelasi soft instalat) pentru a nu avea surprize de genul: problemele nu se pot reproduce.

Productia este cel mai important environment. Toate deploy-urile facute in poductie trebuie sa fie stabile (trecute prin environmentele de testare - testate manual sau automat). Trebuie sa existe posibilitatea de rollback automat - binare (folosind upload history), baze de date (folosind LiquBase sau DBDeploy), cozi de mesaje, etc. Back-up la baza de date de fiecare data cand se face deploy. Este de preferat ca acelasi binar (war, ear) sa treaca perin toate environmentele pan ajunge in productie pentru a evita situatii neplacute. Deploy-ul in productie trebuie sa se faca automat la fel ca in toate celelate environmente (folosind WS API, etc), prin apasarea unui buton putand duce in productie orice modificare de cod (o anumita revizie de pe SVN).

Source control (SVN sau distributed:Git, Mercurial) reprezinta locul in care se afla tot: cod + teste, configurari de aplicatie (deploy), scripturi de build, scripturi de baza de date, etc. Teoretic nimic nu trebuie sa stea inafara - este de preferat sa nu se faca nici un pas manual - ar fi de preferat ca un environment sa fie provizionat si configurat la randul lui din scripturi (Puppet, CHEF) pe langa API-ul care il ofera pentru opearatii de deploy (AWS API, VMWARE API, etc). Orice trebuie sa fie repetabil - reproductibil.

Skills

Ca dezvoltator trebuie sa-ti mentii skill-urile de Linux (Windows) shells scripting (eventual AIX sau alte OS-uri).

Sa stii sa configurezi Hudson (Jenkins) sau orice alt CI server - de fapt as spune ca serverul de integrare devine un fel de panou de control a toate. In fapt el ofera suport pentru integrare cu SVN, are integrare cu uneltele de build, etc. Jenkins este pluginabil, cateva plugin-uri interesante peste cele deja instalate care pot ajuta la deployment pipeline: Jenkins Email Extension Plugin, EnvInject Plugin, build-name-setter, Subversion Release Manager plugin, Jenkins Parameterized Trigger plugin

Folosirea si cunoasterea unui ALM (Application Lifecycle Management) spre exemplu:  JIRA+Confluence+Stash+Bamboo -> Atlassian, IBM Rational solution for Collaborative Lifecycle Management -> IBM sau ThoughtWorks Studios (Mingle+Go+Twist) -> ThoughtWorks, ar aduce un plus de claritate in procesul de dezvoltare.

Probleme care pot aparea

  • Branches hell (pentru clienti diferiti sau pentru fixare de release-uri)
    • a se folosi feature-uri activate/dezactivate
    • a se folosi release-uri la o versiune data (a given version from SVN)
  • Dependencies hell (Maven IVY)
    • a se folosi repository de artefacte
  • Accelerarea deployment-ului in productie
    • nightly build (deploy)

joi, noiembrie 08, 2012

GRAILS - the search is over?



Dupa cum arata acest radar recent de tehnologii care se opreste asupra framework-urilor Web se pare ca Spring MVC, Play si Grails sunt printre castigatori. Daca Spring MVC e de asteptat, GRAILS si Play sunt surprize. In continuare o sa vorbesc despre experienta cu GRAILS din ultima jumatate de an. Cred ca daca Spring este tinta ta, cu GRAILS atunci the search is over. Dar in rest, pentru cealalta jumatate fara Spring (in fapt JEE clasic se bazeaza pe EJB-urile moderne de la 3.0 in sus in care exista deja dependency injection, etc - eu prezic ca intre Spring si EJB piata este jumatate/jumatate) inca cred ca the search is never over. De fapt nu stiu cine e de fapt invingatorul, GRAILS sau Spring!

Interesant in GRAILS


  • Este mai mult decat un framework web (are si parte de middleware: Spring; si persistenta:Hibernate); poate fi numit mai mult un starter de aplicatii (ca Roo, Seam)
  • Este un concurrent pentru Play (bazat pe Java, Scala, Akka, add-ons) - de remarcat ca initial Play pornise tot cu Groovy dar a renuntat in favoarea Scala
  • Sistem pluginabil (in dev time si nu in runtime) dar functional; in general pluginurile sunt infasurari de alte librarii dar adauga constructii specifice Grails (servicii, controlere, tag-uri) care usureaza folosirea lor (e ceva in plus decat simpla lor aducere ca in proiectele cu Maven sau Ivy – dependency management); pluginurile sunt de fapt miniaplicatii Grails impachetate; repository de plugin-uri destul de activ
  • Setat implicit sa creeze schema din entintitati (bazat pe Hibernate); induce astfel un mod de lucru aplecat spre POO si nu spre schema de date (nu se genereaza entitati din schema ca de obicei)
  • Un set clar si fix de stereotypes - archetypes API in denumirea lor (controller, view, serviciu, tag, entitate, command object, etc) toate legate prin injectie folosind default configuration
  • Bazat pe Spring pentru dependency injection (posibilitatea de a face injectare si de beanuri clare de Spring prin xml-uri)
  • Spring via un set de plugin-uri bine definite si intretinute cu grija poate aduce: securitare, accces la retele sociale, acces la baze de date nerelationale, caching, etc (se poate spune ca Grails isi trage seva din Spring)
  • Usurinta in a scrie propriile taguri (mult mai simplu decat in JSP)

Inside GRAILS


  • Librariile externe sunt aduse cu IVY (din cauza ca se foloseste (G)Ant – eventual din repo-uri de Maven)
  • Build inclus – un set de target-uri de ant (Gant = un DSL Groovy echivalent pentru Ant) care pot fi extinse cu propriile scripturi (sau cu scripturi aduse de plugin-uri)
  • Persistenta cu GORM o abstractizare peste Hibernate (sau mai sigur peste Spring Data); ofera transparenta fata de storage – poate fi folosit si peste baze  de date nerelationale
  • Sitemesh deja integrat in aplicatie (layout-uri usor de facut pentru pagini - macro compozitie)
  • Partial template-uri care permit refolosirea de fragmente in pagini (populate cu modele – micro compozitie)
  • Set implicit de tag-uri (tot ce are JSTL si mai mult)
  • Scafolding static si mai ales dinamic (plecand de la entitati) printr-un set de template-uri care la nevoie pot fi modificate spre a genera codul dorit de dezvoltator
  • Configurarea apliatiei cu DSL-uri de Groovy (mult mai usor de accesat programmatic decat XML-urile clasice dar nu decat cu adnotari)
  • Vine implicit cu plugin de tomcat si de hibernate (ele dau versiune distributiei)
  • Suport pentru testare unitara, integrare, functionala (mock-ing dat de framework de orice)
  • URL rewrite inside (nu e nevoie sa se foloseasca alte librarii cu  filtre externe)
  • Populare de date la bootstrap inside (nu e nevoie de scripturi de initializare)
  • Plugin de resources inside by default instalat (nu e nevoie de librarie externa pentru compilare Less, CDN, minimizare, concatenare de resurse:js-uri, css-uri, etc)
  • Un alt scop numit flash – 2 requesturi consecutive
  • Suport de ajax prin tag-uri care infasoara framework-uri JS la alegere (JQuery, etc)
  • GSP pentru view-uri – se foloseste groovy drept expression language
  • Suport pentru scriere de documentatie inside – eport spre PDF, Html
  • Multe g-uri: GSP, GANT, GORM, Groovy, Grails
  • Closures aduse de groovy

Pro GRAILS


  • Hot deploy sau mai bine zis instant reload of classes din cauza naturii dinamice pe care o are Groovy (inclusive in fisierele de proprietati – nu e nevoie de publish via IDE sau tool-uri ca JRebel)
  • Sintaxa redusa (Syntactic Sugar) – groovy e scripting
  • Suport integrat pentru environmente la nivel de aplicatie (ca in Spring)
  • Se poate intercala si cod scris in Java (.groovy-urile se duc tot spre bytecode Java in JVM, groovy este comptibil cu Java – sper ca 100%)
  • Productiv in dezvoltare

Contra GRAILS


  • Slab tipizat (si no compile checking) deci foarte multe probleme se vad doar in runtime (inclusiv typos cum ar fi un nume gresit de metoda care nu este definita si care este totusi apelata)
  • Bazat pe Groovy – limbaj de scripting care nu incurajeaza clean code si o sintaxa ingrijita (de fapt Groovy este foarte relaxat in privinta sintaxei fata de Java care este mai restrictiv; prin definirea de DSL-uri Groovy poate oferi o sintaxa superioara mai apropiata de limbajul natural)
  • Nu functioneaza modificatorii de acces in Groovy - poti executa o metoda chiar daca este private (defavorizeaza incapsularea si ideea de API expus (a la Java))
  • In Groovy nu sunt luate in calcul checked exceptions (deci nu se poate face distinctie intre exceptii de business si exceptii de sistem)
  • Suport defectuos in Eclipse (STS, GST) dar mai bun in IntelijIdea (nu perfect)
  • Nu are validare client side by default (generate from the server side ca in Struts 2)
  • MVC-ul este request/response nu component based (a la JSF) si deci oarecum mai putin productiv
  • Depinde de Groovy (nici o idee despre support – am avut de cateva ori impresia ca unele lucruri nu functioneaza cum m-am astepta) – deci putin probabil sa fie adoptat de firmele mari (care prefera dependenta de JDK-ul de Java mai stabil)
  • Din cauza ca Groovy este limbaj dynamic (multe lucruri se intampla In runtime) este de 2 pana la 4 ori mai lent decat Java (ca infasoara si alte librarii poate sa aduca un alt overtime)

sâmbătă, octombrie 13, 2012

The Scrum Way!

Cateva probleme observate in viata de zi cu zi folosind Scrum - o sinteza de idei care mi s-au parut de folos si le-am notat aici. Daca incepeti un proiect nou sau folositi deja Scrum (agile) in proiectele voastre se poate sa va fie de folos si voua (trebuie sa aveti notiuni de baza de Scrum pentru a intelege cele descrise in continuare).


Nu toti oamenii sunt pregatiti pentru Scrum si agile dar mai ales pentru a dezvolta in echipa; la inceput scoala si mai apoi firmele de la noi nu incurajeaza echipa. Vorbesc aici de ideea de beautifull team cu oameni de valoare asemanatoare lucrand impreuna pe termen lung (indefinit) si nu de chirurg cu asistenti cum se intapla de obicei la noi. La noi se incurajeaza individul (Competence Culture bazata pe specializare, certificari, etc si nu Collaboration or Cultivation Culture). Ca un contra exemplu in scolile din Japonia, elevii fac toate activitatile din timpul zilei  impreuna in grupe iar cea mai mare pedeapsa pentru cineva este aceea de a fi exclus din grup; poate nu intamplator Scrum isi are radacini si in Japonia (Takeuchi and Nonaka - The Scrum Way). Astfel intr-o echipa Scrum trebuie detectati sabotorii si distinsi de cei care sunt doar sceptici (sunt usor de distins pe scrum board, planning, si in general prin atitudinea care o au fata de metodologie) - o solutie pentru sabotori este ca ei sa fie gestionati prin management clasic in afara echipei de Scrum.

De la inceput trebuie respectate principiile fundamentale ale metodologiei Scrum pentru a nu face de fapt dezvoltare adhoc (poate este mai rau decat a folosi efectiv si corect RUP sau orice metodologie neagila dar iterativa - exludem Waterfall despre care este stiut ca este un esec inca din anii 70 in tarile civilizate dar care la noi este folosita pe scara larga -  deoarece esecul sau succesul in proiecte nu conteaza). Empirismul in Scrum vine din reglarile pe care le facem la nivelul acestor reguli de baza (spre exemplu estimarile), dar regulile trebuie respecate absolut si nu arbitrar. De asemenea rolurile in Scrum trebuie respectate si de asemenea metricile trebuie folosite - planning cu estimari, determinarea velocity (cel mai sigur in sprint 3), mentinerea unui ritm continuu: sustainable pace. Daca nu folosim toate acestea, obtinem doar rezultate partiale cum ar fi focusare, sincronizare pentru echipa, unele sprinturi reusite.

Story-urile nu trebuie sa fie use case-uri detaliate - trebuie incurajate discutiile si nu scrierea de documente iar product owner-ul trebuie sa fie mereu disponibil pentru ceilalti pentru a le clarifica in timpul sprint-ului - nu trebuie sa faca o alta activitate (mai grav, el trebuie sa participe la stand up meeting pentru a urmari evolutia storiurilor si a actualiza backlog-ul pentru sprinturile urmatoare - atentie: nu pentru task-uri ci pentru story-urile de pe scrum board); Story-urile trebuie sa aiba o forma as a/when/then care implica si flow nu doar aspecte statice (pagini spre exemplu); pot fi initialal epics sau teme pana la grooming; de asemena, pentru a compensa lipsa specificatiilor, codul trebuie sa fie bine scris (clean code) si acoperit cu teste pentru ca el devine un fel de documentatie a proiectului (deoarece alta documentatie nu exista)

Alte principii care trebuie respectate (ordinea conteaza):
  • trebuie tinut cont ca echipa sa fie cross functional si self managed (cuprinde toti oameni de care e nevoie pentru a implementa scopul sprint-ului si nu e nevoie de nimeni din exterior sa-i gestioneze); cei care participa si in extra activitati trebuie introdusi cu o anumita norma - nu trebuie sa faca alte task-uri inafara de cele din sprint; echipa trebuie sa fie relativ constanta pentru a putea calcula velocity si a se putea forma impreuna
  • trebuie sa se lucreze incremental (un set de features facute end to end si gata de delivery in orice increment - adica nu toata aplicatia in lucru la un moment dat); Scrum este o metodologie agila (embrace change) dar si iterativa (iteratii cu cadenta fixa in timp) si incrementala (increment de funtionalitate la finalul fiecarei iteratii - eventual shipable)
  • a nu se folosi pentru inceput unelte/tool-uri sofisticate pentru ca ele nu salveaza (trebuie physical scrum board cu post its, excel product/release/sprint backlog, planning poker cards); uneltele pot fi folosite ulterior cand exista confidence interval pentru velocity
  • a se evita ownership-ul pe parti ale aplicatiei de catre dezvoltatori (chiar daca e un responsabil pe story sau task care se asigura ca va deveni done - per increment lucreaza mai multi in acelasi timp - cunostintele sunt impartasite de mai multi si se evita expuneri de interfete cu  tot felul de integrari costisitoare)
  • viata de zi cu zi a echipei trebuie sa fie ghidata de evenimentele din Scrum; metodologia trebuie sa devina un mod de viata pentru echipa in orele de lucru (ete inacceptabil ca cineva sa cheme pe ceilalti la meeting-uri!)
  • product owner nu este un project manager ci doar un membu al echipei; el nu trebuie in nici un fel sa opreasca sau limiteze creativitatea echipei - nu este responsabil de cum se implemneteaza intern story-urile; el este parte a echipei si nu un judecator al celorlalti - implicarea lui este activa, zi de zi in viata echipei (demo nu inseamna scaun de judecata si de aceea ar fi mai bine sa fie numit review)
  • definitia lui done trebuie negociata de la inceput si bine stiuta de toti (poate fi mai slaba - functionalitatea de baza si mici bug-uri deschise; sau 0 bugs); done in mod ideal inseamna automated unit/integration tested (inseamna ca membrii echipei sa foloseasca TDD, ATDD de la inceput) - testele automate garanteaza calitatea codului pe termen lung (regresii usor de facut)
  • estimarea se poate face in story points (greu la inceput din cauza diferentelor de intelegere a complexitatii si a alegerii unei referinte relativ la care sa se estimeze) care marcheaza cantitatea de munca sau ideal days care insemna spre exemlu 6 din 8 ore pentru o zi
  • product backlog trebuie sa existe inainte de sprint-uri si trebuie mereu mentinut cu grooming de story-uri si estimari noi de story points or ideal days; este datoria PO; trebuie mentinut intre sprinturi si grooming la fiecare sprint planning meeting
  • in planning evaluarea trebuie facuta pe story-uri de toti (nu doar de catre cel care o sa o implementeze - eventual folosind poker planning ca in XP - deoarece la planning nu se stie cine o sa implementeze efectiv)
  • granularitatea pe scrum board (in cazul in care se folosesc ideal days) trebuie sa fie intre 0.5 si 2 zile
    • daca e mai mica -> micromanagement
    • daca e mai mare -> surprize, surprize
  • burndown chart-ul se deseneaza in functie de estimarea a cat mai e de facut si nu a cat s-a facut (intr-un excel se tin noile estimari) - se taie estimarea de pe task si se pune noua estimare (deci nu conteaza cat timp real se pierde ci cat se estimeaza ca o sa mai fie nevoie - de fapt e o reestimare); de asemenea la calcularea velocity conteaza estimarile initiale si nu timpul real cheltuit per story-uri
  • spatiul de lucru (recomandat sa fie open office) trebuie sa fie conform metodologiei; oarecum oamenii trebuie sa stea toti impreuna; scrum board-ul trebuie sa fie langa ei

joi, octombrie 11, 2012

Posibile probleme de securitate (Web - Java)

Enumar un set de probleme de securitate care pot afecta aplicatiile Web si posibile solutii (in particular aplicatii Java bazate pe containerul de servlets). Am pastrat titlurile tipurilor de atac in engleza. Am sa incerc sa mentin lista si sa adaug si altele noi.

SQL INJECTION

Problema: din cauza crearii de query-uri SQL, HQL, JPQL concatenate folosind String-uri este posibil ca continutul introdus de utilizator sa expuna date din baza de date

Solutie: trebuie verificat ca toate query-urile sunt parametrizate folosind engine-ul de persistenta care escapeaza caracterele speciale in mod automat.  

XSS - STORED 

Problema: continutul introdus in pagina este salvat in baza de date si apare in paginile altor utilizatori (pe comments, etc); odata incarcata pagina scriptul se executa si poate trimite SESSION ID sau alte informatii la o adresa data

Solutia: escape in momentul randarii continutului dinamic (Grails: encodeAsHTML(); encodeAsURL() sau folosind ESAPI); Trebuie urmarit ca utilizatorii cu drepturi mai putine sa nu infecteze pe cei care au drepturi mai multe; spre exemplu un form de sugestii accesibil fara autentificare poate ataca prin injectare direct aplicatia de administrare; utilizatorii se pot infecta intre ei printr-un forum in care isi trimit unul altuia comentarii

XSS REFLECTED

Problema: un parametru proaspat introdus este afisat pe site fara escape; un user poate forma un url folosind acest parametru pentru a injecteaza JS in pagina si invita pe altii sa vada acest URL; la randare se executa scriptul respectiv (se poate fura session id)

Solutia: escape in momentul randarii valorii parametrilor care vin direct din request (Grails: encodeAsHTML(); encodeAsURL() sau folosind ESAPI)

MAN IN THE MIDDLE

Problema: chiar daca unele pagini au SSL (pagina de login sa zicem sau cele care contin date despre carduri - IBAN-uri) si nu se poate vedea spre exemplu parola sau alte date confidentiale de pe aceste pagini, pe paginile care nu au SSL pe acel site se pot totusi vedea alte date precum SESSION ID cookie care pot fi folosite pentru session hijacking;

Solutie: tot site-ul trebuie pus pe SSL pentru a evita orice furt de session id; trebuie stabilit daca site-ul contine date de business care pot afecta grav pe utilizator caz in care se face total SSL (exemplu ar fi aplicatiile Google care sunt total sub SSL certificat) sau este un site de entertainment caz in care se poate pune SSL doar pe unele pagini; in orice caz in site este recomandat ca schimbarea de parole sau date importante sa se faca cu parola curenta


DENIAL OF SERVICE

Problema: un user rau intententionat poate incarca sistemul prin apelari succesive de operatii costisitoare facandu-l sa cada sau sa se blocheze (se poate folosi orice tool de load prin inregistrare de scenariu via proxy si repetarea lui paralelizata); chiar daca aplicatia nu este blocata, se pot incarca costurile de hosting daca plata se face per resurse consumate (rularea injectorului poate fi fara sfarsit spre exemplu)

Solutie: folosirea de form token-uri (mecanism deja implementat in Web frameworks: Struts sau Grails) care ar face ca request-urile de pe aceeasi sesiune sa se execute oarecum secvential; trebuie tinut cont ca sesiunile/IP cu care sunt trimise cererile pot fi diferite si deci aceasta solutie este doar partiala; introducerea de limite clare pentru a diminua complexitata operatiei

BRUTE FORCE

Problema: este posibila incercarea de a face brute force pe pagina de login (sau orice pagina care implica credentials) prin incercarea repetitiva a unui numar mare de parole (folosind dictionare si/sau rainbow tables)

Solutiii: introducerea de CAPTCHA pe pagina dupa un numar de incercari (per IP si/sau session); suplimentar, folosirea de token-uri ca in Denial of service (ar opri paralelismul doar la nivel de sesiune); cea mai buna idee este audit pe login pentru a vedea IP-urile de unde vin atacurile (cereri multiple) si a le bana pentru un timp; o alta solotie este blocarea contului dupa un numar de incercari si deblocare la cerere; de tinut cont ca request-ul se poate face prin proxy care poate schimba ip-ul la nivel de protocol inainte de a atinge aplicatia tinta; de asemenea id-ul de sesiune poate fi schimbat mai ales daca pagina atacata nu este sub autentificare


GUESSABLE ID's

Problema: in aplicatie se vehiculeaza id-uri din baza de date (nu neaparat vizibile in query string: hidden fields, cookies, sau parametri vizibili in consola browserului/mesahe HTTP); de obicei id-urile din baza sint consecutive si deci sunt usor de intuit; userii cu aceleasi roluri in aplicatie pot sa vada date ale altor useri care au acelasi rol ca ei

Solutia: de evitat folosirea de id-uri in aplicatie; verificarea conditiilor de business cand se fac cereri cu id-uri (daca userul logat are voie sa le vada); folosirea altor identificatori (folosinf URL rewrite) care sa nu fie usor de ghicit (nume in loc de id daca de exeplu numele este oricum public - trebuie sa fie si unic)


WRONG URL ACCESS

Problema: este posibil ca rolurile sa nu fie bine puse pe pagini astfel incat unele pagini pot fi vazute de cei care nu au dreptul; acelasi lucru pentru apelurile de AJAX - fragmente de pagini pot ramane nesecurizate; sau unele pagini de administrare ale aplicatiei au ramas expuse dupa ce dezvoltarea s-a terminat - eventual consola de server, etc; sau erorile aplicatiei sunt logate direct in productie atunci cand se intampla

Solutie: trebuie intretinuta mereu o lista de pagini cu rolurile asociate (trebuie sa fie acoperita declarativ cu rolurile corespunzatoare in web.xml in cazul securitatii clasile JEE, security.xml sau la nivel de controlere cu adnotari in Spring); la aparitia unei erori se va redirecta spre o pagina cu eroare (404 - page not found; 403 - no rights for this page; 500 - server internal error)
    

 

   

   

vineri, mai 18, 2012

JavaScript <= Java (Web)

Cu mirare asistam la o evolutie spectaculuoasa pentru Java Script. Ce este foarte clar este ca merita sa fie urat in trecut pentru incompatibilitatile dintre browsere - si l-am evitat pe cat am putut pentru asta. Dar in ziua de azi capata din ce in ce mai multa insemnatate, mai ales odata cu HTML5 (HTML 5 nu e doar o inbunatatire adusa pentru HTML ci e un intreg runtime independend de browser care ofera aplicatiilor capabilitati nebanuite) si aplicatiile pentru mobile.

Intre timp problemele de incompatibilitate intre browsere s-au rezolvat prin aparitia framework-urilor JS precum JQuery, Dojo, etc. Acestea permit aces spre DOM indiferent de browser, apeluri de AJAX transparente fata de browser, etc. Lucrand cu un framework precum JQuery spre exemplu, ai senzatia ca e o reactualizare a paradigei "Scrie o data ruleaza oriunde", acum nu la nivel de OS ci la nivel de browser. Un API standat, un fel de SDK care e independent de browser - si cum browserul sta pe un OS - e independent si de sitem de operare.

Pe langa aceasta asemanare intre framework-uri JS si Java mai sunt si altele. Ani de zile am programat "on the server side" respectand paradigma MVC (patternul MVC) cu framework-uri precum Struts 2 (1), Spring MVC sau implementari de JSF. Supriza cea mai mare este ca se poate si fara MVC on the server side, si refresh pe toata pagina - ceea ce circula intre client si server trebuie sa fie numai datele sub forma de JSON sau XML (text). De fapt de ce nu am folosi MVC in client iar serverul sa fie accesat doar via Web Services? BlackboneJS este chiar un astfel de framework (dar nu e singurul). E un MVC la nivel de JS, frumos implementat, care aduce claritate aplicatiei tale prin folosire si care separa clar partea de View, de partea de Contoller si cea de Model. Modelul se populeaza din partea de server folosindu-se apeluri REST/AJAX transportant JSON peste HTTP - transformarea mesajelor in obiecte JS este instantanee.

Apelurile asincrone/sincrone se pot face explicit cu JQuery sau direct in Blackbone.js (doar apeluri REST, partea de server nu mai genereaza markup HTML). Securizarea pe partea de server pentru WS REST se poate face cu OAuth sau prin REST API key. La nivel de view se pot folosi template-uri statice in care se se injecteaza modelul dinamic adus de pe server. Se pot folosi si alte librarii pentru templating - precum Mustache. Submit-ul de form-uri se face la fel cu AJAX.Validari se fac on the client side cu JQuery validation plugin spre exemplu. Rutarea paginilor se poate face cu un router intern Blackbone.js sau cu unul extern: JQuery Mobile Router spre exemplu. Localizarea se poate face cu pluginuri de JQuery. Pentru sintaxa simplificata (ca un fel de Groovy pentru Java) exista CoffeeScript.

Ce lipseste in JavaScript este modularitatea. In Javascript nu exista ca in Java includere de pachete in unitatea de compilare  (fisierul .java), nu exista modificatori de acces pentru a limita vizibilitatea intre pachete. Dar si pentru acestea exista solutii: RequireJS. Si ca tabloul sa fie complet trebuie sa enumeram si framewor-uri pentru TDD: QUnit, BDD: Jasmine si altele care fac posibila testarea la nivel de JavaScript.

Nu am vorbit despre partea de mobile - am spus doar ca o mare parte din importanta pe care o capata JavaScript vine de aici (browserele integrate in mobile sunt mai avansate in ce priveste implementarea noilor standarde). Ei bine pentru mobile avem o serie de framework-uri (combinate cu CSS) specifice: Dojo Mobile, JQuery Mobile si Sencha Tauch. Aceste framework-uri aduc seturi de componente specializate pentru mobile, care se randeaza perfect pe aceste dispozitive adaptandu-se chiar din look-and feel-ul nativ - spre deosebre de o pagina standard HTML care se afiseaza (si doar atat). La fel se randeaza pe o gama larga de dispozitive adaptandu-se la un set mare de browsere. Responsive web design este un principiu care sta la baza acestor framework-uri si implica randarea automata a paginii in mod corect la dimensiunile display-ului dispozitivului.

Tot in lumea mobila, este de remarcat PhoneGap, tot o librarie Javascript care ofera transparenta fara de tipul de mobil utilizat (iOS, Android, BlackBerry, webOS, Symbian) oferind un API standard apelabil JavaScript prin care se pot accesa functii native ale dispozitivelor - spre exemplu acces la agenda de contacte din telefon, la pozitia GPS, etc. PhoneGap aduce de asemenea local storage astfel incat aplicatia poate rula in izolare urmand a sincroniza datele cu partea de server.

Unelte utile:


vineri, mai 11, 2012

A/B Tests (Lean)

Testele A/B (Split Tests) sunt foarte putin cunoscute. Pentru mine a fost o mare mirare cand am auzit de ele. Ca o recapitulare. Exista teste unitare (in izolare). Exista mocks, stubs, dummy objects. Exista teste de integrare (integration tests). Teste functionale (automate sau nu). Exista TDD. Exista BDD. Exista acoperire cu teste. Existe test case-uri. Exista teste de regresie. Exista UAT -  user acceptance tests. Exista teste de performanta si load. Exista biblioteci Java: JUnit, TestNG | JMock,Mockito | DBUnit, HTTPUnit | JBehave | JMeter, etc.

De unde vin A/B Tests? Din alta lume! Daca setul de practici enumerat mai sus vin din metodologiile agile (incluzand Scrum si XP) in care testatea unitara/automata constituia o practica de baza, A/B tests vin din lean, metodologia la baza careia sta eliminarea pierderii de timp (en. eliminate waste). Ce e WASTE intr-un proiect, orice consuma resurse si nu aduce valoare. Unul din principalele motive de pierdere de timp este implementarea de functionalitati pe care nu le foloseste nimeni. Cazul extrem este cel al unui intreg produs pe care nu il foloseste nimeni.

Cum e posibil sa creezi un produs pe care nu il foloseste nimeni? Una din cele mai comune situatii este aceea in care clientul este necunoscut - adica nu iti cunosti inca cllientii (alta posibilitate este ca cel ce reprezinta clientul in agile, sa nu il reprezinte de fapt). Te adresezi unei piete in care tu crezi ca exista o problema care merita rezolvata - care ti-ar putea  permite sa construiesti ceea ce se cheama un "self sustenable business". In acest caz nu are cine sa-ti mai spuna care din story-uri aduc valoare, nu are cine sa mai vada demo-urile, etc. Practic esti gata sa construiesti un  produs pe care nimeni nu il vrea.

Deci suntem gata sa implementam o noua functionalitate (feature) in aplicatia noastra (incremental - o adaugam unui set de functionalitati pe care le-am implementat deja - toate legate incontinuu prin integrate continua). Daca folosim Agile, reprezentantul clientului care sta on site cu tine ar trebui sa aleaga dintr-un backlog of features pe cea mai valoroasa. In stil agile se implementeaza si se livreaza clientului la demo pentru a o valida - UAT. Dar ce se intampla in cazul in care nu-ti stii clientii? Ar trebui facut acelasi lucru - ar trebui validata intr-un fel.  Iar validarea in acest caz o faci cu A/B tests - pentru ca acestea iti ofera posibilitatea de a vedea daca festure-ul tau aduce valoare sau nu clientilor.

Putem spune in acest caz ca nu avem o functionalitate de implementat ci o ipoteza de testat = experiment de facut (daca o ipoteza cade la teste se elimina functionalitatea din spate). Avem deci un experiment care are mai multe ipoteze (una din ipoteze este aplicatia ta fara noua functionalitate) - fiecare ipoteza cu un procent de  utilizatori/vizitatori care iau parte la el. Se urmaresc in site o serie de metrici care spun clar cum a influentat acel experiment experienta utilizatorilor/vizitatorilor cu aplicatia.

Deci se ia functionalitatea si se face asa (un exemplu in care se experimenteaza o a doua pagina de landing cu un alt continut:  UVP schimbat, design, etc.):
String[] firstHypothesis = { "landing_1", "50" };
String[] secondHypothesis = { "landing_2", "50" };

Hypothesis hypothesis = cohortsManager.setupVisitorsExperiment("LANDING PAGE",
getRequest().getRemoteHost(), firstHypothesis, secondHypothesis);

Se creaza pe loc experimentul daca nu exista (se salveza in baza de date cu tot cu ipoteze asociate si si cu procentele lor). Se returneaza ipoteza in care e utilizatorul curent - daca face deja parte din experiment se returneaza ipoteza pe care o avea. Daca e nou i se asociaza o ipoteza astfel incat sa se respecte procentele stabilite per experiment. Ipoteza se foloseste in redirectarea vizitatorului spre o pagina de landing sau alta.

Mergand la extrem in a compara/deosebi Agile cu Lean: story-urile se transforma in experimente (ipoteze care trebuie testate). Testele de acceptanta clientului se transforma in split (A/B) teste. Integrarea continua se tranforma in livrare continua (continous delivery) - functionalitatile implementate se expun repede in fata clientului pentru a fi validate. Scrum Board se transforma in Kanban - limitare clare de task-uri care se implementeaza la un moment dat pentru a nu creea functionalitati pe care nu le folosesc nimeni = maximixare de pierdere de timp. Deci daca se infunda pe undeva board-ul, trebuie desfundat pentru a merge mai departe - nu continuam sa il infundam. Dezvoltatorul este implicat de la un capat la altul in dezvoltarea task-ului - incluzand validarea care e o interactiune indirecta cu clientii.

Actionable Metrics