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

TRANSCRIPT

  • 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 & Mr. Hyde

2. ACTO I - Los personajesdesymfony 2013 Dr. Jenkins & Mr. Hyde 3. Mr. HydeBodaclickdesymfony 2013 Dr. Jenkins & 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 & Mr. Hyde 5. desymfony 2013 Dr. Jenkins & Mr. Hyde 6. Dr. JenkinsCoredesymfony 2013 Dr. Jenkins & Mr. Hyde 7. REST PHP 5.4 Symfony 2.1.x LAM SQLite Redis con Twemproxy MongoDB RabbitMQ Jenkins, PHPUnit & Capifony SatisDr. Jenkinsdesymfony 2013 Dr. Jenkins & 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 & Mr. Hyde 9. ACTO II - Envuelvelo en una API "REST"desymfony 2013 Dr. Jenkins & Mr. Hyde 10. EntidadesSobrenaturalesdesymfony 2013 Dr. Jenkins & Mr. Hyde 11. Las bases de datosBBDD 1BBDD 3 BBDD 4BBDD 2desymfony 2013 Dr. Jenkins & 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 & Mr. Hyde 13. public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs){if ($this->kernel->getEnvironment() != test) {return;}$classMetadata = $eventArgs->getClassMetadata();$assoMap = $classMetadata->getAssociationMappings();foreach ($assoMap as $asso) {if (isset($asso["joinTable"])) {$asso["joinTable"]["name"] = str_replace(".", "_", $asso["joinTable"]["name"]);$classMetadata->setAssociationOverride($asso["fieldName"],$asso);}}$tableName = $classMetadata->getTableName();$classMetadata->setPrimaryTable(array(name => str_replace(".", "_", $tableName)));}Hackeando las DQLdesymfony 2013 Dr. Jenkins & Mr. Hyde 14. desymfony 2013 Dr. Jenkins & Mr. HydeUn Jenkins feliz 15. API Legacy.../api/[public|secured]/legacy/...desymfony 2013 Dr. Jenkins & Mr. Hyde 16. //namespace BDKLegacyBundleTestsControllerLegacyController;//PostPublicUserControllerTest$user = [legacy => [...],core => [...],];$client->request(POST, "/api/public/legacy/novio{$oauthString}",$user, array());API Legacy - Envodesymfony 2013 Dr. Jenkins & Mr. Hyde 17. //namespace BDKLegacyBundleController;// class UserPublicControllerpublic function postNovioAction(Request $request){$view = FOSView::create();$viewData = $this->container->get(bdk.legacy.rest_manager)->postUser($request, ProfileType::USER);return $view->setStatusCode($viewData[status])->setData($viewData[data]);}API Legacy - Recepcindesymfony 2013 Dr. Jenkins & Mr. Hyde 18. API Bridge.../api/[public|secured]/...desymfony 2013 Dr. Jenkins & Mr. Hyde 19. //Legacy$user = ["legacy" => [...],"core" => [...],];//Bridge$user = ["name" = "", "surname"= "", .... ];$client->request(POST, "/api/public/users{$this-> oauthString}&profile=user",$user, array());API Legacy - Envodesymfony 2013 Dr. Jenkins & Mr. Hyde 20. // namespace BDKLegacyBundleController;// class BridgeUserPublicControllerpublic function postUsersAction(Request $request, $profile){$em = $this->get(doctrine.orm.legacy_entity_manager);//...$mapper = new CoreArrayToLegacyNovioArrayMapper($em);$coreArray = $request->request->all();$params = [core => $coreArray,legacy => $mapper->map($coreArray)];$request->request->replace($params);$view = FOSView::create();$viewData = $this->container->get(bdk.legacy.rest_manager)->postUser($request, ProfileType::USER);return $view->setStatusCode($viewData[status])->setData($viewData[data]);}API Legacy - Recepcindesymfony 2013 Dr. Jenkins & Mr. Hyde 21. ACTO III - Dos en unodesymfony 2013 Dr. Jenkins & Mr. Hyde 22. FrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioOAuthLogindesymfony 2013 Dr. Jenkins & Mr. Hyde 23. FrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioOAuth + Token WSSE (login)Logindesymfony 2013 Dr. Jenkins & Mr. Hyde 24. FrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioInfo delusuarioAcceso al perfil del usuarioOAuth + Token WSSE (login)Logindesymfony 2013 Dr. Jenkins & Mr. Hyde 25. Perfil delusuarioEnlaces a la plataforma antiguaLoginFrontalloginnicoApp.nuevaApp.antiguaPerfil delusuarioInfo delusuarioOAuth + Token WSSE (login)Acceso al perfil del usuariodesymfony 2013 Dr. Jenkins & Mr. Hyde 26. Internet ReverseProxyPerfil del usuario - Reverse Proxybodaclick.com/^((?!my).)*$bodaclick.com/mydesymfony 2013 Dr. Jenkins & Mr. Hyde 27. desymfony 2013 Dr. Jenkins & Mr. Hyde 28. Perfil del usuario - Reverse Proxydesymfony 2013 Dr. Jenkins & Mr. HydeInternet ReverseProxybodaclick.com/^((?!my).)*$bodaclick.com/myiframe 29. ACTO IV - Sangre, sudor y migracionesdesymfony 2013 Dr. Jenkins & 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 > 6 GBAPI Legacy - Mapeodesymfony 2013 Dr. Jenkins & Mr. Hyde 31. desymfony 2013 Dr. Jenkins & Mr. Hyde 32. Fuerza brutaMigracionesdesymfony 2013 Dr. Jenkins & Mr. Hyde 33. protected function migrateUser($override, $limit = 0){//...foreach ($oldUsers as $oldUser) {try {$userArray = $mapper->getUserCoreArray($oldUser);$userArray = $this->trimUserArray($userArray);$coreUser = $this->persistToCore($userArray, $oldUser, $override);$oldUser->setNewId($coreUser->getUser()->getId());$this->legacyEm->persist($oldUser);$this->legacyEm->flush();} catch (Exception $e) {//...}}}Migracin por comando nicodesymfony 2013 Dr. Jenkins & Mr. Hyde 34. DivididasMigracionesdesymfony 2013 Dr. Jenkins & Mr. Hyde 35. MigrateUserCommand RabbitMQConsumidor de MapeosDatos mapeadosMigracin en dos pasosdesymfony 2013 Dr. Jenkins & Mr. HydeMySQL MySQLApp. nueva App. antigua 36. protected function migrateUser($override, $limit = 0){//...foreach ($oldUsers as $oldUser) {try {$userArray = $mapper->getUserCoreArray($oldUser);//Usamos RabbitMQ$data[oldUser] = $oldUser;$data[userArray] = $userArray;$this->getContainer()->get(old_sound_rabbit_mq.migration_producer)->publish($serializer($data));} catch (Exception $e) {//...}}//...}Migracin por comando y consumidordesymfony 2013 Dr. Jenkins & Mr. Hyde 37. protected function execute(AMQPMessage $migration){//...try {$coreUser = $this->persistToCore($userArray, $oldUser, $override);$oldUser->setNewId($coreUser->getUser()->getId());$this->legacyEm->persist($oldUser);$this->legacyEm->flush();} catch (Exception $e) {//...}//...}Migracin por comando y consumidordesymfony 2013 Dr. Jenkins & Mr. Hyde 38. PerezosasMigracionesdesymfony 2013 Dr. Jenkins & Mr. Hyde 39. class SecurityController extends Controller{public function postTokenAction(){//...$username = $request->get(_username);$password = $request->get(_password);$preLoginEvent = new PreUserLoginEvent($username,$password);$this->get(event_dispatcher)->dispatch(UserEvents::PRE_LOGIN, $preLoginEvent);//...}}Migracin por evento - Lanzamientodesymfony 2013 Dr. Jenkins & Mr. Hyde 40. ...Perezosas (Listener)//namespace BDKLegacyBundleEventListener;//class UserLoginCreateUserProfileListenerpublic function onPreUserLogin(PreUserLoginEvent $event){//...$coreUser = $this->legacyUserManager->createCoreUser($userArray,ProfileType::USER,[Create, Default]);//...}Migracin por evento - Listenerdesymfony 2013 Dr. Jenkins & Mr. Hyde 41. Perezosas,asncronas einversasMigracionesdesymfony 2013 Dr. Jenkins & Mr. Hyde 42. Evento asncrono comunicado al driverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins & Mr. Hyde 43. //abstract class AsyncWeddingEvent implements AsyncEventInterface;//class PostCreatWeddingEvent extends AsyncWeddingEvent;$event = new PostCreateWeddingEvent();$event->setWedding($wedding);$event->setUserProfile($userProfile);$this->container->get(bdk.async_event_dispatcher)->dispatch($event);Evento asncrono lanzadodesymfony 2013 Dr. Jenkins & Mr. Hyde 44. Evento asncrono comunicado al driverListener/Publicadoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins & Mr. Hyde 45. Evento asncrono para un sistema pub/subSistema Pub/SubListener/Publicadoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins & 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 & Mr. Hyde 47. Evento asncrono para un sistema pub/subSistema Pub/SubSubscriptor MySQLMySQLListener/Publicadoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins & Mr. HydeApp. nueva App. antigua 48. Evento asncrono para un sistema pub/subConsumidor MySQLMySQLListener/Productoro DriverAsyncEventDispatcherControladorEventopropiodesymfony 2013 Dr. Jenkins & Mr. Hyde*.wedding.eventRabbitMQTopic ExchangeApp. nueva App. antigua 49. //BDKLegacyBundleEventListenerAsyncWeddingEventListenerclass WeddingEventListener implements ConsumerInterface{//...if ($wedding->getProvince()) {$legacyCountry = $this->legacyEm->getRepository(BDKLegacyDbBundle:Pais)->findOneByCodPais($wedding->getProvince()->getCountry());$legacyProvince = $this->legacyEm->getRepository(BDKLegacyDbBundle:Provincia)->findOneBy([idPais => $legacyCountry->getId(), provincia =>$wedding->getProvince()->getName()]);$legacyEventUser->setProvinciaId($legacyProvince->getId());}//...}Consumidordesymfony 2013 Dr. Jenkins & Mr. Hyde 50. MixtasMigracionesdesymfony 2013 Dr. Jenkins & Mr. Hyde 51. Migracin perezosa mixtaMongoDbMySQLMySQLLegacyInternetInternetdesymfony 2013 Dr. Jenkins & Mr. HydePerfil delusuarioApp. antiguaApp. nueva 52. //postLoad//...$service = $em->getClassMetadata(BDKWeddingBundle:Wedding)->reflClass->getProperty(service);$service>setAccessible(true);$service>setValue($wedding,$this->dm->getReference(BDKWeddingBundle:Service,$wedding->getServiced()));Cargar datos desde MongoDBdesymfony 2013 Dr. Jenkins & Mr. Hyde 53. ACTO V - Routingdesymfony 2013 Dr. Jenkins & Mr. Hyde 54. /var/.../reportajes/45.php//45.php$ruta = "/desymfony-2013.html";//...Urls fsicasdesymfony 2013 Dr. Jenkins & 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 & Mr. Hyde Texto bodaclick.com/desymfony-2013.html//desymfony-2013.html$idReportaje = 45;cargaContenido();//... 56. desymfony 2013 Dr. Jenkins & 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 & 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 & Mr. Hyde 59. ?desymfony 2013 Dr. Jenkins & Mr. Hyde