De symfony 2013 dr. jenkins y mr. hyde - slides-842359017

Download De symfony 2013   dr. jenkins y mr. hyde - slides-842359017

Post on 25-Jun-2015

1.388 views

Category:

Documents

0 download

Embed Size (px)

TRANSCRIPT

<ul><li> 1. Dr. Jenkins y Mr. HydeActo I - Los personajesActo II - Envuelvelo en una API "REST"Acto III - Dos en unoActo IV - Sangre, sudor y migracionesActo V - URLs y Redisdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde</li></ul> <p> 2. ACTO I - Los personajesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 3. Mr. HydeBodaclickdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 4. PHP 4 Spaghetti western Ausencia MVC Inicio del desarrollo en 2000 Reescritura del 90% en 2007 + de 25 desarrolladores 4 Bases de datos Ms de 1.5M de lneas de cdigo Formado por: Directorio, CRM+ERP, Lista de bodas,Estadisticas, Extranet para clientes, CMS, rea decontenidos, WebTV, Etc.Mr. Hydedesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 5. desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 6. Dr. JenkinsCoredesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 7. REST PHP 5.4 Symfony 2.1.x LAM SQLite Redis con Twemproxy MongoDB RabbitMQ Jenkins, PHPUnit &amp; Capifony SatisDr. Jenkinsdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 8. Joel Spolsky (Stack Overflow co-founder) dijo:(sobre Netscape)" Bueno, si. Lo hicieron. Lo hicieron al tomar la peordecisin estratgica que una empresa de software puede hacer:decidieron re-escribir el cdigo desde 0"fuente: http://www.joelonsoftware.com/articles/fog0000000069.htmlDan Milsten, fundador de Hub8, en un post en On Startups (publicadopor Dharmesh Shah, inversor de Stack Exchange):"Preprate para que este proyecto no termine jams.Lo primero yabsolutamente crtico que tienes que entender sobre empezar unareescritura es que va a tomar muchsimo ms de lo que esperas. Inclusodespus de que quitas el tpico optimismo del desarrollador. He aquporqu: Migrar datos es lo peor que puedes echarte a la cara, ms allde cualquier otra cosa.fuente: http://onstartups.com/tabid/3339/bid/97052/How-To-Survive-a-Ground-Up-Rewrite-Without-Losing-Your-Sanity.aspxRe-escribir desde 0, segn los expertosdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 9. ACTO II - Envuelvelo en una API "REST"desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 10. EntidadesSobrenaturalesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 11. Las bases de datosBBDD 1BBDD 3 BBDD 4BBDD 2desymfony 2013 Dr. Jenkins &amp; Mr. HydeBBDD 1BBDD 3 BBDD 4Relacionadas entre si por claves extranjeras mantenidas por software 12. //namespace BDKLegacyDbBundleEntity;/*** @ORMTable(name="boda.CLIENTE")* @ORMEntity*/class Cliente{//.../*** @ORMManyToMany(targetEntity="Tags")* @ORMJoinTable(name="bodamoll.b_tags",* joinColumns={@ORMJoinColumn(name="id_cliente", referencedColumnName="ID")},* inverseJoinColumns={@ORMJoinColumn(name="id_tag", referencedColumnName="id")}* )*/private $id_tag;//...Hackeando las DQLdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 13. public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs){if ($this-&gt;kernel-&gt;getEnvironment() != test) {return;}$classMetadata = $eventArgs-&gt;getClassMetadata();$assoMap = $classMetadata-&gt;getAssociationMappings();foreach ($assoMap as $asso) {if (isset($asso["joinTable"])) {$asso["joinTable"]["name"] = str_replace(".", "_", $asso["joinTable"]["name"]);$classMetadata-&gt;setAssociationOverride($asso["fieldName"],$asso);}}$tableName = $classMetadata-&gt;getTableName();$classMetadata-&gt;setPrimaryTable(array(name =&gt; str_replace(".", "_", $tableName)));}Hackeando las DQLdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 14. desymfony 2013 Dr. Jenkins &amp; Mr. HydeUn Jenkins feliz 15. API Legacy.../api/[public|secured]/legacy/...desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 16. //namespace BDKLegacyBundleTestsControllerLegacyController;//PostPublicUserControllerTest$user = [legacy =&gt; [...],core =&gt; [...],];$client-&gt;request(POST, "/api/public/legacy/novio{$oauthString}",$user, array());API Legacy - Envodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 17. //namespace BDKLegacyBundleController;// class UserPublicControllerpublic function postNovioAction(Request $request){$view = FOSView::create();$viewData = $this-&gt;container-&gt;get(bdk.legacy.rest_manager)-&gt;postUser($request, ProfileType::USER);return $view-&gt;setStatusCode($viewData[status])-&gt;setData($viewData[data]);}API Legacy - Recepcindesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 18. API Bridge.../api/[public|secured]/...desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 19. //Legacy$user = ["legacy" =&gt; [...],"core" =&gt; [...],];//Bridge$user = ["name" = "", "surname"= "", .... ];$client-&gt;request(POST, "/api/public/users{$this-&gt; oauthString}&amp;profile=user",$user, array());API Legacy - Envodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 20. // namespace BDKLegacyBundleController;// class BridgeUserPublicControllerpublic function postUsersAction(Request $request, $profile){$em = $this-&gt;get(doctrine.orm.legacy_entity_manager);//...$mapper = new CoreArrayToLegacyNovioArrayMapper($em);$coreArray = $request-&gt;request-&gt;all();$params = [core =&gt; $coreArray,legacy =&gt; $mapper-&gt;map($coreArray)];$request-&gt;request-&gt;replace($params);$view = FOSView::create();$viewData = $this-&gt;container-&gt;get(bdk.legacy.rest_manager)-&gt;postUser($request, ProfileType::USER);return $view-&gt;setStatusCode($viewData[status])-&gt;setData($viewData[data]);}API Legacy - Recepcindesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 21. ACTO III - Dos en unodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 22. FrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioOAuthLogindesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 23. FrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioOAuth + Token WSSE (login)Logindesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 24. FrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioInfo delusuarioAcceso al perfil del usuarioOAuth + Token WSSE (login)Logindesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 25. Perfil delusuarioEnlaces a la plataforma antiguaLoginFrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioInfo delusuarioOAuth + Token WSSE (login)Acceso al perfil del usuariodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 26. Internet ReverseProxyPerfil del usuario - Reverse Proxybodaclick.com/^((?!my).)*$bodaclick.com/mydesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 27. desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 28. Perfil del usuario - Reverse Proxydesymfony 2013 Dr. Jenkins &amp; Mr. HydeInternet ReverseProxybodaclick.com/^((?!my).)*$bodaclick.com/myiframe 29. ACTO IV - Sangre, sudor y migracionesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 30. 4 bases de datos Datos inconsistentes Emails repetidos Fechas como 0000-00-00 Enums Tenemos tablas con ms de 100 campos Campos por defecto a 0000-00-00 Tablas tanto innodb como MyISAM Cotejamientos diferentes (utf8, latin) Tablas &gt; 6 GBAPI Legacy - Mapeodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 31. desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 32. Fuerza brutaMigracionesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 33. protected function migrateUser($override, $limit = 0){//...foreach ($oldUsers as $oldUser) {try {$userArray = $mapper-&gt;getUserCoreArray($oldUser);$userArray = $this-&gt;trimUserArray($userArray);$coreUser = $this-&gt;persistToCore($userArray, $oldUser, $override);$oldUser-&gt;setNewId($coreUser-&gt;getUser()-&gt;getId());$this-&gt;legacyEm-&gt;persist($oldUser);$this-&gt;legacyEm-&gt;flush();} catch (Exception $e) {//...}}}Migracin por comando nicodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 34. DivididasMigracionesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 35. MigrateUserCommand RabbitMQConsumidor de MapeosDatos mapeadosMigracin en dos pasosdesymfony 2013 Dr. Jenkins &amp; Mr. HydeMySQL MySQLApp. nueva App. antigua 36. protected function migrateUser($override, $limit = 0){//...foreach ($oldUsers as $oldUser) {try {$userArray = $mapper-&gt;getUserCoreArray($oldUser);//Usamos RabbitMQ$data[oldUser] = $oldUser;$data[userArray] = $userArray;$this-&gt;getContainer()-&gt;get(old_sound_rabbit_mq.migration_producer)-&gt;publish($serializer($data));} catch (Exception $e) {//...}}//...}Migracin por comando y consumidordesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 37. protected function execute(AMQPMessage $migration){//...try {$coreUser = $this-&gt;persistToCore($userArray, $oldUser, $override);$oldUser-&gt;setNewId($coreUser-&gt;getUser()-&gt;getId());$this-&gt;legacyEm-&gt;persist($oldUser);$this-&gt;legacyEm-&gt;flush();} catch (Exception $e) {//...}//...}Migracin por comando y consumidordesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 38. PerezosasMigracionesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 39. class SecurityController extends Controller{public function postTokenAction(){//...$username = $request-&gt;get(_username);$password = $request-&gt;get(_password);$preLoginEvent = new PreUserLoginEvent($username,$password);$this-&gt;get(event_dispatcher)-&gt;dispatch(UserEvents::PRE_LOGIN, $preLoginEvent);//...}}Migracin por evento - Lanzamientodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 40. ...Perezosas (Listener)//namespace BDKLegacyBundleEventListener;//class UserLoginCreateUserProfileListenerpublic function onPreUserLogin(PreUserLoginEvent $event){//...$coreUser = $this-&gt;legacyUserManager-&gt;createCoreUser($userArray,ProfileType::USER,[Create, Default]);//...}Migracin por evento - Listenerdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 41. Perezosas,asncronas einversasMigracionesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 42. Evento asncrono comunicado al driverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 43. //abstract class AsyncWeddingEvent implements AsyncEventInterface;//class PostCreatWeddingEvent extends AsyncWeddingEvent;$event = new PostCreateWeddingEvent();$event-&gt;setWedding($wedding);$event-&gt;setUserProfile($userProfile);$this-&gt;container-&gt;get(bdk.async_event_dispatcher)-&gt;dispatch($event);Evento asncrono lanzadodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 44. Evento asncrono comunicado al driverListener/Publicadoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 45. Evento asncrono para un sistema pub/subSistema Pub/SubListener/Publicadoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 46. //Resources/config/async_drivers.ymlservices:bdk.wedding.async_event_driver_create:class: BDKWeddingBundleModelEventDispatcherAsyncDriverRabbitMQDriverarguments: [@old_sound_rabbit_mq.wedding_event_producer, @serializer]calls:- [setRoutingKey, [create.wedding.event]]tags:- { name: bdk.async_event_dispatcher, event: bdk.async.post_create_wedding }Configuracin del driverdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 47. Evento asncrono para un sistema pub/subSistema Pub/SubSubscriptor MySQLMySQLListener/Publicadoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins &amp; Mr. HydeApp. nueva App. antigua 48. Evento asncrono para un sistema pub/subConsumidor MySQLMySQLListener/Productoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins &amp; Mr. Hyde*.wedding.eventRabbitMQTopic ExchangeApp. nueva App. antigua 49. //BDKLegacyBundleEventListenerAsyncWeddingEventListenerclass WeddingEventListener implements ConsumerInterface{//...if ($wedding-&gt;getProvince()) {$legacyCountry = $this-&gt;legacyEm-&gt;getRepository(BDKLegacyDbBundle:Pais)-&gt;findOneByCodPais($wedding-&gt;getProvince()-&gt;getCountry());$legacyProvince = $this-&gt;legacyEm-&gt;getRepository(BDKLegacyDbBundle:Provincia)-&gt;findOneBy([idPais =&gt; $legacyCountry-&gt;getId(), provincia =&gt;$wedding-&gt;getProvince()-&gt;getName()]);$legacyEventUser-&gt;setProvinciaId($legacyProvince-&gt;getId());}//...}Consumidordesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 50. MixtasMigracionesdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 51. Migracin perezosa mixtaMongoDbMySQLMySQLLegacyInternetInternetdesymfony 2013 Dr. Jenkins &amp; Mr. HydePerfil delusuarioApp. antiguaApp. nueva 52. //postLoad//...$service = $em-&gt;getClassMetadata(BDKWeddingBundle:Wedding)-&gt;reflClass-&gt;getProperty(service);$service&gt;setAccessible(true);$service&gt;setValue($wedding,$this-&gt;dm-&gt;getReference(BDKWeddingBundle:Service,$wedding-&gt;getServiced()));Cargar datos desde MongoDBdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 53. ACTO V - Routingdesymfony 2013 Dr. Jenkins &amp; Mr. Hyde 54. /var/.../reportajes/45.php//45.php$ruta = "/desymfony-2013.html";//...Urls fsicasdesymfony 2013 Dr. Jenkins &amp; Mr. Hydebodaclick.com/desymfony-2013.html//desymfony-2013.html$idReportaje = 45;cargaContenido();//... Texto 55. Urls via redisSET www.bodaclick.com:reportaje:45/desymfony-2013.htmldesymfony 2013 Dr. Jenkins &amp; Mr. Hyde Texto bodaclick.com/desymfony-2013.html//desymfony-2013.html$idReportaje = 45;cargaContenido();//... 56. desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 57. @etorras79etorras@BodaclickITEnrique Torras, como Mr. Hyde Ingeniero en Informtica Desarrollando web desde 2004 Actualmente dirige el rea dedesarrollo en Bodaclickdesymfony 2013 Dr. Jenkins &amp; Mr. Hydeslideshare.net/etorras 58. @eguliasegulias Desarrollador web desde 2006 Coqueteando con Symfony (yotros frameworks) desde 2007 Miembro de Symfony Madrid Actualmente trabajando comolder de equipo en Bodaclick@BodaclickITEduardo Gulias, como Dr. Jenkinsslideshare.net/eguliasjoind.in/talk/view/8834desymfony 2013 Dr. Jenkins &amp; Mr. Hyde 59. ?desymfony 2013 Dr. Jenkins &amp; Mr. Hyde</p>