applicazioni distribuite con symfony2
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
10ottobre2014,SymfonyDay,Milano
[email protected](Utilities)...maanchefotografoeviaggiatore
[email protected]/thinkindieinstagram.com/thinkindie
Facile.itèuncomparatoreditariffe
assicurativeenergetiche(luceegas)telefoniche(ADSL,fissoemobile)mutui,contibancarieprestiti
InostriufficisonoaMilano,masoprattutto...
StackLAMP/LEMPSymfony/ZendElasticSearchNode.jsRabbitMQRedisEmber.js/AngularJS/Backbone.jsVagrant/Ansible/Puppet
SiamopresentianchesuGitHubgithub.com/facile-it
Bunny
SeparazionetrafrontendebackendMultibusinessRicercaglobaleACL,anchenellaricercaGestionediprocessiinbackground
WebService RESTful basatosull'esistenza di (ades. leentità
diDoctrine)dicuisihaaccessoalleloro tramite un
globale(URI).
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}
FOSRestBundleFOSOAuthServerBundleFOSUserBundleJSONAPI(Ember.jsDriven)
Semplifica e velocizza lo sviluppodi unWebServiceRESTful
gestionedeicodiciHTTPdirispostadifferenti view handlers perdifferentivaloridiAcceptURLREST-friendly
/***@RouteResource("Compagnia")*/classCompagnieControllerextendsBunnyController{/***@View()*/publicfunctioncgetAction(){}/***@View()*/publicfunctiongetAction(Request$request){}/***@View()*/publicfunctionpostAction(Request$request){}/***@View()*/publicfunctionpatchAction(Request$request){}/***@View()*/publicfunctiondeleteAction(Request$request){}}
UnbundledibaseperilWS
Unbundleperognibusiness(ADSL,Luce&Gas,Mobile),
differenti alpiùperunnumero ristrettodi entitàodi
comandiinbackground
Un bundle per ciascuna altra attività cross-
business(es.:inviodiSMS)
Posso rapidamente ricercare unqualsiasi documento contenenteunqualsiasitermineFOSElasticaBundle: le entità diDoctrine vengono persisteanchesuElasticSearch
SmartReindexing: la modifica diunaentità richiede l'aggiornamentodi tutti i documenti in cui ècontenuta
$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à
ACL= ccess ontrol istPermettono di definire regole ( )capillariperaccederearisorse.Es.: permessi dei files supiattaformeUnix,regoledelfirewall.
La gestione base delle ACL vieneaffidata al provider di default diSymfony e vengono persistite suMySQL
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;}
Utilizzare il provider di default diSymfony per filtrare una collezione dientità non è nésoddisfacente.
Youknow,forsearch!
QuandounaentitàvienesalvatasuElasticSearchildocumentovienedivisoindueparti
:contenenteleACL"espanse":l'entitàveraepropria
{"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"}]}}
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);
Utilizzandoifiltri(dalladocumentazionediES):
nonvienecalcolatolo_scoreperognidocumento,ma
vieneapplicataunalogicabooleana
irisultatidimoltifiltripossonoesseresalvatiincache
restringo la query sui documenti effettivamente
ricercabili,ottimizzandolaquerystessa
Redis è un database di tipo chiave-valore,dovelachiave,comeilvalore,possono essere una qualsiasisequenzadibytes.
http://redis.io
Redisèutilizzabileper:
CachingavanzatoRankingsintemporealeContatoriPub/SubCode
BunnyutilizzaRedisperlacachedi
MetadatidiDoctrineQuery(DQL SQL)RisultatidellequeryEntità
doctrine:orm:entity_managers:bunny:metadata_cache_driver:type:redishost:localhostport:6380query_cache_driver:type:redishost:localhostport:6380result_cache_driver:type:redishost:localhostport:6380
Redis viene utilizzato anche per lagestionedi codeconResque tramitephp-resque.Qualsiasi operazione cheparticolarmente complessa vienedemandata quindi ad un processoasincronooprogrammato.
Esempidiprocessiasincroni:
SmartReindexingGenerazionediReportCaricamento su account FTPesterniCaricamentibatchsugestionaliditerzi
https://joind.in/talk/view/12215