Applicazioni distribuite con Symfony2

34
10 ottobre 2014, Symfony Day, Milano

description

La sezione Utilities di Facile.it ha recentemente riscritto il proprio applicativo interno utilizzando Ember.js con Ember Data che si appoggia a sua volta ad un WebService REST realizzato in PHP tramite Symfony2 full-stack e alcuni bundle messi a disposizione dall'ecosistema di Symfony per gestire Redis, ElasticSearch, ACL e quant'altro si è reso necessario. Durante la presentazione verranno discusse le motivazioni che hanno portato a scegliere ciascun componente, come è stato integrato all'interno dell'applicativo, in quali problematiche ci si è imbattuti e come sono state risolte.

Transcript of Applicazioni distribuite con Symfony2

Page 1: Applicazioni distribuite con Symfony2

10ottobre2014,SymfonyDay,Milano

Page 2: Applicazioni distribuite con Symfony2

[email protected](Utilities)...maanchefotografoeviaggiatore

[email protected]/thinkindieinstagram.com/thinkindie

Page 3: Applicazioni distribuite con Symfony2

Facile.itèuncomparatoreditariffe

assicurativeenergetiche(luceegas)telefoniche(ADSL,fissoemobile)mutui,contibancarieprestiti

InostriufficisonoaMilano,masoprattutto...

Page 4: Applicazioni distribuite con Symfony2

StackLAMP/LEMPSymfony/ZendElasticSearchNode.jsRabbitMQRedisEmber.js/AngularJS/Backbone.jsVagrant/Ansible/Puppet

SiamopresentianchesuGitHubgithub.com/facile-it

Page 5: Applicazioni distribuite con Symfony2
Page 6: Applicazioni distribuite con Symfony2

Bunny

Page 7: Applicazioni distribuite con Symfony2

SeparazionetrafrontendebackendMultibusinessRicercaglobaleACL,anchenellaricercaGestionediprocessiinbackground

Page 8: Applicazioni distribuite con Symfony2
Page 9: Applicazioni distribuite con Symfony2

WebService RESTful basatosull'esistenza di (ades. leentità

diDoctrine)dicuisihaaccessoalleloro tramite un

globale(URI).

Page 10: Applicazioni distribuite con Symfony2

GET/api/users/1HTTP/1.1Host:ws.bunny.facile.itAccept:application/vnd.api+json

HTTP/1.1200OKContent-Type:application/vnd.api+jsondate:Thu,19Oct201414:38:16GMT

{"id":1,"timestamp":"2014-06-10T15:42:37+02:00","lastUpdateTimestamp":"2014-06-10T15:42:37+02:00","username":"BunnyWs","nome":"Bunny","cognome":"WS","email":"[email protected]","isActive":true}

Page 11: Applicazioni distribuite con Symfony2

FOSRestBundleFOSOAuthServerBundleFOSUserBundleJSONAPI(Ember.jsDriven)

Page 12: Applicazioni distribuite con Symfony2

Semplifica e velocizza lo sviluppodi unWebServiceRESTful

gestionedeicodiciHTTPdirispostadifferenti view handlers perdifferentivaloridiAcceptURLREST-friendly

Page 13: Applicazioni distribuite con Symfony2

/***@RouteResource("Compagnia")*/classCompagnieControllerextendsBunnyController{/***@View()*/publicfunctioncgetAction(){}/***@View()*/publicfunctiongetAction(Request$request){}/***@View()*/publicfunctionpostAction(Request$request){}/***@View()*/publicfunctionpatchAction(Request$request){}/***@View()*/publicfunctiondeleteAction(Request$request){}}

Page 14: Applicazioni distribuite con Symfony2

UnbundledibaseperilWS

Unbundleperognibusiness(ADSL,Luce&Gas,Mobile),

differenti alpiùperunnumero ristrettodi entitàodi

comandiinbackground

Un bundle per ciascuna altra attività cross-

business(es.:inviodiSMS)

Page 15: Applicazioni distribuite con Symfony2

Posso rapidamente ricercare unqualsiasi documento contenenteunqualsiasitermineFOSElasticaBundle: le entità diDoctrine vengono persisteanchesuElasticSearch

Page 16: Applicazioni distribuite con Symfony2

SmartReindexing: la modifica diunaentità richiede l'aggiornamentodi tutti i documenti in cui ècontenuta

Page 17: Applicazioni distribuite con Symfony2

$inheritanceTree=$this->getInheritanceTree($rootEntity);$entities=$this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames();foreach($entitiesas$entity){$class=$this->cmf->getMetadataFor($entity);$associationMappings=$class->getAssociationMappings();if(empty($associationMappings)){continue;}else{foreach($associationMappingsas$nestedEntity){if(in_array($nestedEntity['targetEntity'],$inheritanceTree)){...}}}}

DoctrineMetadata:hogiàunamappa(ricorsiva)dellerelazionitraentità

Page 18: Applicazioni distribuite con Symfony2

ACL= ccess ontrol istPermettono di definire regole ( )capillariperaccederearisorse.Es.: permessi dei files supiattaformeUnix,regoledelfirewall.

Page 19: Applicazioni distribuite con Symfony2

La gestione base delle ACL vieneaffidata al provider di default diSymfony e vengono persistite suMySQL

Page 20: Applicazioni distribuite con Symfony2

Le ACE vengono definite in ciascunaentitàtramitecustomannotationsnamespaceFacile\Ws\BunnyBundle\Entity;useFacile\Ws\BunnyBundle\Annotation\EntityAceasACE;/***@ACE("ROLE",name="ROLE_ADMIN",mask="MASK_MASTER");*@ACE("ROLE",name="ROLE_USER",mask="MASK_VIEW");*/classCompagnia{/***@ACE("ROLE",name="ROLE_USER",mask="MASK_VIEW")*@ACE("ROLE",name="ROLE_ADMIN",mask="MASK_MASTER")*/protected$nome;}

Page 21: Applicazioni distribuite con Symfony2

Utilizzare il provider di default diSymfony per filtrare una collezione dientità non è nésoddisfacente.

Page 22: Applicazioni distribuite con Symfony2

Youknow,forsearch!

Page 23: Applicazioni distribuite con Symfony2

QuandounaentitàvienesalvatasuElasticSearchildocumentovienedivisoindueparti

:contenenteleACL"espanse":l'entitàveraepropria

Page 24: Applicazioni distribuite con Symfony2

{"data":{"lastUpdateTimestamp":"2014-10-08T09:28:45+02:00","id":5,"timestamp":"2014-06-10T15:42:33+02:00","venduto":true,"nome":"Facile.it","type":"energia"},"meta":{"acl":[{"mask":1,"name":"role_user","type":"role"},{"name":"role_admin","mask":64,"type":"role"}]}}

Page 25: Applicazioni distribuite con Symfony2

Laricercadidocumentivieneeseguitacon\Elastica\Queryefiltrataconiruoliricopertidall'utenteattivo$elasticaFilterOr=new\Elastica\Filter\BoolOr();foreach($this->getUserExpandedRoles()as$role){$elasticaFilterRolesName=new\Elastica\Filter\Term();$elasticaFilterRolesName->setTerm('meta.acl.name',strtolower($role));$elasticaFilterRolesType=new\Elastica\Filter\Term();$elasticaFilterRolesType->setTerm('meta.acl.type','role');

$elasticaFilterAndRole=new\Elastica\Filter\BoolAnd();$elasticaFilterAndRole->addFilter($elasticaFilterRolesName);$elasticaFilterAndRole->addFilter($elasticaFilterRolesType);

$elasticaFilterOr->addFilter($elasticaFilterAndRole);}

$elasticaQuery=new\Elastica\Query(new\Elastica\Query\MatchAll());$elasticaQuery->setFilter($elasticaFilterOr);

Page 26: Applicazioni distribuite con Symfony2

Utilizzandoifiltri(dalladocumentazionediES):

nonvienecalcolatolo_scoreperognidocumento,ma

vieneapplicataunalogicabooleana

irisultatidimoltifiltripossonoesseresalvatiincache

restringo la query sui documenti effettivamente

ricercabili,ottimizzandolaquerystessa

Page 27: Applicazioni distribuite con Symfony2

Redis è un database di tipo chiave-valore,dovelachiave,comeilvalore,possono essere una qualsiasisequenzadibytes.

http://redis.io

Page 28: Applicazioni distribuite con Symfony2

Redisèutilizzabileper:

CachingavanzatoRankingsintemporealeContatoriPub/SubCode

Page 29: Applicazioni distribuite con Symfony2

BunnyutilizzaRedisperlacachedi

MetadatidiDoctrineQuery(DQL SQL)RisultatidellequeryEntità

Page 30: Applicazioni distribuite con Symfony2

doctrine:orm:entity_managers:bunny:metadata_cache_driver:type:redishost:localhostport:6380query_cache_driver:type:redishost:localhostport:6380result_cache_driver:type:redishost:localhostport:6380

Page 31: Applicazioni distribuite con Symfony2

Redis viene utilizzato anche per lagestionedi codeconResque tramitephp-resque.Qualsiasi operazione cheparticolarmente complessa vienedemandata quindi ad un processoasincronooprogrammato.

Page 32: Applicazioni distribuite con Symfony2

Esempidiprocessiasincroni:

SmartReindexingGenerazionediReportCaricamento su account FTPesterniCaricamentibatchsugestionaliditerzi

Page 33: Applicazioni distribuite con Symfony2
Page 34: Applicazioni distribuite con Symfony2

https://joind.in/talk/view/12215