Perfil de GabrielBiztalk Blandengue (http...FotosBlogListasMais ![]() | Ajuda |
|
29/6/2008 Un PAR de días mejorando mis deployments Biztalk - Parte 4Voy a incluir un Setup de Visual Studio para mi deployment y ver si lo puedo integrar con la implementación con Nant. Para esto, agregué un proyecto de Setup a mi proyecto y agregué los Project Outputs para orquestaciones, esquemas, transformaciones y assemblies utilitarias. Es importante que los agregue con la información de Debug (porque así está configurado). Agrego los archivos que no forman parte de solución:
La estructura de directorios debe quedar como se ve debajo Luego creé shortcuts para los wizards de deploy/redeploy/undeploy y moví los shortcuts al User Program y les cambié los nombres para que fueran más "user-friendly" dentro de un folder.
Hago el Build y luego de instalar tengo el mismo comportamiento que con WiX (pero sin WiX). Estoy más que contento. Ahora a ver qué más puedo mejorar del resto de la instalación. 28/6/2008 Un día mejorando mis deployments Biztalk - Parte 3Una de las cosas que normalmente pasa en los proyectos es que los settings de los diferentes artefactos en el binding es diferente. Para experimentar con esto, decidí usar el EnvironmentSettingManager que se aplica dentro del deploymentframework. La primera cosa que ví es que a pesar de que la documentación expresa que al cerrar la planila se actualizan los archivos (por una macro), esto no sucede, pero es fácilmente subsanable usando el utilitario EnvironmentSettingsExporter.exe que está en el subdirectorio DeployTools. Con esto quedé conforme pero dejaré esta configuración para más adelante, dado que ahora quiero crear un instalador con WiX Creando el instalador con WiX Lo primero es copiar el directorio BizTalkSample.WiXSetup y renombrarlo con NombreProyecto delante en nuestra solución, luego renombrar el BiztalkSample.WiXSetup.build con NombreProyecto delante y yo lo incluí en el directorio "Solution Items" por comodidad. Hay que masajear un poco el archivo, no olvidar generar los GUIDs diferentes para el installer. Luego hay que ejecutar nant en el directorio setup debajo de WixSetup (no hay path, pero está donde nosotros mismos lo copiamos ;)), y no encontrará los archivos:
que deben copiarse del directorio raíz de la solución de ejemplo a nuestro directorio raíz. corriendo Nant luego de esto, generó el MSI. El MSI solamente instala los archivos, y genera entradas en el menú Start para que se pueda implementar la versión. Corrí el MSI, pero no generó las entradas de implementar/desimplementar, por lo que solo me quedó ir al panel de control y desinstalar el producto, y a empezar a pensar por qué no quedó bien instalado. Round 1- Verificar que el BtsSample funciona: Generé el instalador y lo instalé, quedando correctamente instalado. Round 2 - Por qué no quedó instalado: . Toqué el BizTalk.WiXSetup.nant comentando la línea debajo relacionada a DeploymentTest dado que en mi ejemplo no tengo. pero eso no ayudó, dado que provocó otro error. Creo que el error es que siempre intenta invocar con un deploymentTest aunque en el archivo NombreProyecto.sln.deploy.build yo tengo esa variable en false. Creé entonces una solución NombreProyecto.DeploymentTest con un test que siempre de correcto. Hay que crear también un app.config con los valores que tiene el app.config de la solución de ejemplo. Creado el archivo .config, copiarlo en la raíz del proyecto. Hecho todo esto, los errores desaparecieron, sin importar lo que hayas puesto en IncludeDeploymentTest genera el "Verify Deployment" y nada más. Esto para mí es un bug, pero tengo que investigarlo más adelante. Lo que sí encontré es por qué no me genera el resto, es porque (y tuve que buscarlo bastante), el script generate-install-script.js de WiX modificado que está en el directorio WiXSetup\Setup, busca en la raíz del proyecto los archivos:
Para incluirlos en el menú. Estos .bat están en la raíz del directorio de la aplicación de ejemplo (junto con otros .bat que hay que copiar para que estos funcionen). El final de la búsqueda - ¿vale la pena? No quiero caer en la disonancia cognitiva que es lo que hace que mis amigos del pinguino piensen que "si es tan difícil, seguro que debe valer la pena, no es que soy un tarado masoquista, es que realmente vale la pena :)". El problema al que nos enfrentamos cuando tenemos que hacer una distribución Biztalk, hoy, es que las alternativas no son buenas. Normalmente en cualquier distribución tenemos los siguientes requerimientos:
Por lo anterior, pareciera que vale la pena tener toda esa infraestructura, sobretodo teniendo en cuenta la cantidad de utilitarios y casos que comprende el instalador. Además, por lo que vi, hay dos complejidades conceptuales:
Haciéndolo fácil, sustituyendo WiX ¿Podemos hacer esto con un proyecto de setup? Lo que necesito es:
Así que voy a mi parte 4 y luego cuento cómo me fue. 27/6/2008 Un día mejorando mis deployments Biztalk - Parte 2Para comenzar a mejorar, tomé uno de mis proyectos y lo primero que he hecho es cambiar los .btproj para que donde dice Development diga Debug y donde dice Deployment diga Release. Luego fui a la solución y en clic derecho/configuration manager cambié todos a Debug. Cambié mi solución .Maps a .Transforms e hice lo mismo con el directorio correspondiente, además, modifiqué el nombre del assembly generado, aunque no el namespace (para no tener que cambiar referencias y re-hacer el deployment. Copié el directorio DeployTools de la solución de ejemplo a un subdirectorio en mi solución y creé el directorio DeployResults. Creé una nueva "Solution Folder" y la nombré "Solution Items" poniendo dentro los archivos BizTalkDeploymentInclude.nant y BizTalkSample.sln.deploy.build (renombrado como NombreSolucion.sln.deploy.build) que copié de la solución de ejemplo al directorio raíz de la solución. Preparar algo de trabajo, realizar el deployment de la solución Ahora debemos realizar el deployment de la solución (si ya no lo tenemos hecho) y generar el archivo de binding directamente con el Biztalk Deployment Wizard con el nombre NombreSolucion.PortBinding.xml en la raíz de la solución. Agregamos el archivo a la solución dentro del folder "Solution Items". Modificar el archivo de build Abrí el NombreSolucion.sln.deploy.build y modifiqué los siguientes datos:
Nótese que uno de los assemblies no tiene prefijo. Comenté el customDeployTarget y el applyFilePerms dado que no lo necesitaba. Comenté el environmentsettings aunque es algo que realmente me va a servir pero quiero seguir avanzando. La prueba Luego de hacer todo lo anterior, simplemente eliminé la aplicación del servidor completamente y di Tools/BT-Biztalk Deploy en mi solución. Falla, porque no alcanza con comentar el environmentsetting, igualmente llama para generar los parametros de modo que hay que copiar el directorio EnvironmentSettings de la solución de ejemplo a nuestra solución. Siguiendo con la prueba, lo siguiente que cae es cuando quiere hacer el xmlpreprocess de NombreSolucion.PortBindingsMaster.xml esto es algo que esperaba, dado que el usingmasterbindings está en true, lo volví a false junto con la propiedad applyXmlEscape Y ahora sí, estamos listos para más. Un día mejorando mis deployments Biztalk - Parte 1Luego de mucho tiempo y diferentes alternativas, he decidido comenzar a usar el Biztalk Deployment Framework http://www.codeplex.com/biztalkdeployment del amigo Scott Colestock. Lo primero es bajar los todos los paquetes de Release de codeplex y descompactar el que tiene el Sample en la máquina donde tenemos Biztalk 2006 R2. El documento "BT2006DeployWithNantDocs.doc" parece destilar toda la información que necesitamos, al menos para comenzar. Hallazgo 1 : nombre de los assemblies Los assemblies deben tener una forma específica para que el deployment por defecto de Nant que está incluido (BizTalkDeploymentInclude.nant) los tome y esa estructura es NombreProyecto.TipoAssembly, donde TipoAssembly puede tomar los valores:
Continuando la búsqueda Lo siguiente a mirar es el archivo BizTalkSample.sln.deploy.build, donde está una instancia de uso del BiztalkDeploymentInclude.nant (está incluído). Además, las propiedades applyXmlEscape y usingMasterBindings están en true para indicar que se usa PortBindingsMaster.xml Un apartado especial en este archivo es la sección customDeployTarget que permite ejecutar comandos específicos que no son atendidos por el Core. En el ejemplo se usa para dar permisos a directorios al usuario con el que corre el servicio Biztalk Server que aloja al host. A probar (pero primero a terminar de instalar) Después de leer la introducción, lo siguiente es empezar a probar. Para esto lo que sigue es seguir los pasos del apéndice A del documento. Lo primero es instalar NUnit, la versión recomendada en el documento que yo tengo es la 2.2.8, pero la que está disponible en el sitio es la 2.4.0, hay que bajar el que dice win .net 2.0. No me coincidieron la cantidad ni los nombres de los assemblies de test pero funcionó, por lo que supongo debo seguir adelante. Ahora me bajo el Nant, que es la 0.85 pero full ya no es Rc, hay que bajar la nant-0.85-bin.zip y descompactarlo en c:\program files\Nant, luego bajar el NantContrib y descompactar los directorios haciendo el merge de los directorios (no debajo de bin como dice el doc). Lo que se necesita de ahí en adelante forma parte del Core por lo que llegó la hora de descompactar el BTS2006DeployWithNantCore en un directorio (que yo llamé con ese mismo nombre) y copiar el BizTalk.NAnt.Tasks.dll en el bin de Nant. En el nant.exe.config quité todos los supportedRuntime excepto el de la versión v2.0.50727. Luego de esto, es necesario instalar las herramientas para visual studio que están en un .zip diferente (BT2006DeployWithNAntExtraTools) y correr el script MakeBizTalkExternalTools_VS2005.vbs en la carpeta MakeBizTalkExternalTools_VS2005 (y esto ya parece la instalación de una distribución de nuestro amigo el pinguino :), espero que esto sí valga la pena). Aquí, si tenemos abierto Visual Studio, debemos cerrarlo y abrirlo, abriendo nuevamente la solución de ejemplo, hacemos el Rebuild All y luego Tools/BT-Biztalk Deploy y .... hay que mirar bien! Deberíamos tener en la consola de Administración, la aplicación Biztalksample con orquestaciones, mapas, esquemas y pipelines, en la GAC debiéramos ver 5 assemblies con prefijo BiztalkSample. Creo el directorio c:\temp\BizTalkSample_OutDir y agrego la cuenta IWAM al grupo BizTalk Isolated Host users group (yo uso W2003) Levante Nunit para correr el test que abrí de la carpeta recién compilada bin\debug y lo que obtuve fue un error de archivo no encontrado buscando testfiles debajo del directorio. Caí en la cuenta que hay que probar con la dll que ya viene en la raíz del src, pero al intentar cargarla no encuentra nunit.framework que copié junto con el xml del bin\debug donde intenté inicialmente. Ahora lo probé y todo funciona bien como prueba la figura debajo, aunque no gané todavía el entendimiento global de la solución, un par de horas después de comenzar, mi infraestructura está funcionando 24/6/2008 Como recibir un string desde el MQSC Adapter (receive string mqsc adapter)En realidad esta solución funciona para cualquier caso donde tenga que recibir un string y llevarlo a una orquestación donde el mensaje en el receive shape queramos que sea un string. En el caso particular del adapter para MQSeries (o WebSphere MQ), de tipo cliente (que se instala con el CD de HIS), lo que recibo del adaptador es lo que está en el mensaje, con todos los datos de lo que sería el contexto del MQMessage en el contexto del mensaje Biztalk. El problema es que si ingreso con un pipeline passthrough, Biztalk no procesará la suscripción, no entraré en detalles pero si les interesa lo que sucede se explica en el artículo de la Kb a continuación http://support.microsoft.com/kb/837860/en-us Una posible solución es usar un RawString para la entrada como se explica en esta entrada http://www.traceofthought.net/CommentView,guid,c5418f3d-2ea7-4530-ab9c-ae4c49154fcb.aspx el único tema con esto es que hay que hacer el deployment no solamente del ContextAdder (ContextAdder) , sino del RawString, y usarlo en la orquestación. Asumiendo que entienda el artículo y cómo hacerlo, no es una mala solución. La otra solución es tener un ContextAdder que además de agregar al contexto la propiedad MessageType como se ve debajo al tipo string, agregue al string raw que viene, el xml <string></string> alrededor del string original que entra. Aquí ContextAdderModificado subo la solución con un ContextAdder modificado que hace lo anterior. Igualmente persiste, si necesitamos escribir WebSphere MQ via el MQSC Adapter la necesidad de usar un RawString por lo que en el mismo proyecto está incluida la clase RawString del SDK. Hay una orquestación que asume que están los artefactos correctamente implementados para probar y recibe un string y envía un string (con una lógica de dominio que puede quitarse si quieren probarse strings simples). Ya que estamos, comento un par de cosas importantes para interactuar con MQSC. 1) en el Receive, los siguientes parámetros son mandatorios: Channel Name, Queue y Queue Manager 2) en el Send los párámetros mandatorios son: Channel Name, Connection Name, Queue y Queue Manager Si estos parámetros no están, los errores 2058 con una descripción como Reason code 2058 Failure encountered while attempting to open queue pueden sucederse sin que esto nos indique exactamente qué está sucediendo. Por qué no creo en EF (Entity Framework) ni L2S (Linq To Sql)Realmente el título debería reflejar que no creo en ORM (Object -Relation Mapping), porque en mi opinión ORM refleja siempre una lógica CRUD, y CRUD es permitir que la base de datos dirija el diseño técnico y arquitectural del software (en lugar de los requerimientos de negocio). Y no creo que eso sea una buena idea Tomemos un ejemplo. Un típico ejemplo de una transacción sería hacer que un joven cambie su tutor en la facultad; otra podría ser cambiar su sexo para convertirse en una joven. Resolvemos las dos transacciones de la misma manera. Leemos el registro del joven en la base de datos, lo traemos a la interfaz de usuario, dejamos que el usuario cambie los campos que deben ser cambiados, enviamos el registro modificado al servidor, actualizamos la fila de la tabla usando control de concurrencia optimista. Eso es todo CRUD, y sería una correlación perfecta para el software ORM. Pero este diseño está dirigido por la base de datos y no por el negocio. Estas dos transacciones no tienen ninguna relación. Si hay un cambio de tutor al mismo tiempo que la persona se está cambiando el sexo, es una "pura coincidencia". Una mejor manera de exponer esto es con dos operaciones separadas: - CambiarTutor(IdPersona, idNuevoTutor) -CambiarSexo(IdPersona, Fecha) [Aquí se podría argumentar que es necesario tener el NuevoSexo pero no quiero entrar en ese detalle ahora) Lo anterior no es CRUD, y podría permitir crear un joural de transacciones. De hecho, la mejor manera para que los componentes de acceso a datos lo manejen sería realizar un insert SQL en el journal, y dejar que la base de datos afecte correctamente las filas en las tablas correspondientes. En ambientes de alta contención esto sería muy saludable, dado que diferentes usuarios con diferentes conexiones competirían solamente por Insert, que es mucho menos serio en términos de lock que si estuvieran compitiendo por updates como sucede en las situaciones CRUD. Entiendo que CRUD es a veces necesario y lo correcto, pero sostengo que está lejos de ser siempre la mejor cosa. Me da mucho miedo que usando software ORM, los desarrolladores estén tentados de usar CRUD cuando no deberían. No solamente esto, sino que, dado que resolver todos los problemas de ORM es complejo, los programadores más "osados" (y muchas veces sin experiencia), de analizar el código fuente de algunos de estos ORM, concluyan que es la mejor manera de construir software, y terminemos encontrando (ayer encontré algo de esto y por eso me motivo a escribir) monstruos de siete cabezas para resolver funcionalidad trivial. Por otro lado el SQL necesario es casi siempre trivial. Se que no todos los programadores pueden ser expertos en el arte de escribir SQL, pero no tienen por qué. De la misma manera es cierto que no todos los programadores son expertos en crear interfaces de usuario (mi caso), pero tampoco tenemos por qué ser. Debería ser posible en cualquier proyecto no trivial, usar las personas buenas para cada cosa en la misma. En esta línea de pensamiento está SOA, yo creo en SOA y no veo que ORM haga viable el "mindset" necesario para que estos suceda, no porque sea inútil como herramienta (aunque de hecho, en mi opinión no sirve, porque genera un overhead enorme para operaciones triviales), sino porque mina desde las raíces el pensamiento conceptual de los diseñadores y programadores del software. |
|
|