Generación Grunge en su máxima expresión…

Solo si han vivido debajo de una piedra no sabrán que el Grunge fue un movimiento que transformó la música a como la conocemos actualmente.  Si fuiste adolecente en la década de los noventas (especialmente a principio de), sabrás perfectamente de lo que estoy hablando.  No niños/as no todo en la vida es U2, Rasmus o Amandititititita: NO.

Y bueno, como buen exponente de esa época y de la Generación X me gustaría mostrarles un pequeño tesoro para que se deleiten sus pupilas.  Considerados como Patrimonio Rockero de la Humanidad por la UNESCO, este par de drumsticks engalanarán una de las paredes de mi nuevo hogar:

Así es, un par de drumsticks autografiados por el mismísimo, incomparable, grandioso, poderoso y legendario Matt Cameron; especialmente para mí =D.  Que cóooomo los conseguí??? Eso es secreto de Estado.  Es como decirles cómo ganar la lotería, o decirles exactamente cuántos vuelos de Aeroméxico llegarán retardados hoy (sí, son más de 20 :) ),…. no no no.

Salu2! :)

Políticas en Workflow Foundation

Políticas en Workflow Foundation

Como ya hemos visto en capítulos anteriores, una regla es un conjunto de expresiones condicionales que nos permiten evaluar ciertos valores para determinar un resultado verdadero o falso. En este capítulo profundizaremos un poco más acerca de las reglas y su relación que guardan con los Conjuntos de Reglas o RuleSet, usado por la actividad Policy.

La actividad Policy y los Conjuntos de Reglas

La actividad llamada Policy nos permite en un flujo de trabajo evaluar un RuleSet, el cuál es una colección de reglas relacionadas o no entre sí.

El Conjunto de Reglas o RuleSet es una colección de reglas relacionadas o no entre sí. Nos referimos a que dos o más reglas están relacionadas entre sí cuando ellas leen o actualizan el mismo campo o propiedad de alguna clase.

Veamos ahora en la práctica cómo podemos utilizar esta actividad dentro de nuestros flujos de trabajo en Workflow Foundation.

Para comenzar, abramos Visual Studio .NET si es que no está actualmente abierto. Posteriormente crearemos un nuevo proyecto llamado PolicyWF de tipo Sequential Workflow Console Application tal y como lo muestra la siguiente figura:

Ya que deseamos mostrar la funcionalidad de la actividad Policy, junto con la evaluación de su RuleSet relacionado, necesitamos escribir un poco de funcionalidad para nuestro flujo de trabajo. Sin embargo, esta es una tarea muy sencilla: vamos a crear cuatro variables públicas de tipo int llamadas a, b, c y d. Estas variables (comúnmente denominados “campos”) le permitirán al RuleSet evaluar sus reglas y su posible re-evaluación. Muy bien, manos a la obra. Hagamos clic en el botón “View Code” de la ventana Solution Explorer de Visual Studio.NET para desplegar la vista de código de nuestro flujo de trabajo. Posteriormente escribamos el código para crear esas variables a nivel de clase:

Ahora, necesitamos asignarle un valor a cada variable para que las reglas en el RuleSet que vamos a crear lean esos valores. Esto lo podemos hacer inmediatamente después de la invocación al método InitializeComponent() en el constructor de la clase:

El siguiente paso es seleccionar la actividad Policy del Toolbox y arrastrarla al diseñador de Workflow Foundation. Cuando la actividad es colocada en el diseñador, automáticamente Visual Studio .NET le asigna un nombre el cual en nuestro caso eso policyActivity1. Asimismo esta actividad muestra un símbolo de admiración en color rojo, esto significa que la actividad aun no ha sido configurada (tal y como sucede al configurar una actividad de tipo IfElseActivity como vimos en los capítulos anteriores).

Como podemos apreciar en la ventana de propiedades, la actividad policyActivity1 tiene una propiedad llamada RuleSetReference, la cual indica el nombre del RuleSet que deseamos asociar a esa actividad. Ya que en este caso acabamos de crear un proyecto nuevo no tenemos un RuleSet definido. Esto lo podemos hacer en la caja de diálogo llamada “Select Rule Set”, la misma que es desplegada al hacer clic en el botón con tres puntos “…” en la propiedad RuleSetReference de policyActivity1 tal y como lo muestra la siguiente figura:

Esta caja de diálogo nos permite crear, modificar o eliminar los Conjuntos de Reglas que hayamos definido dentro de nuestro proyecto. Ya que no tenemos nada definido aún, es buena idea hacer clic en el botón “New…” para poder crear un nuevo RuleSet. Al hacer clic en este botón Visual Studio .NET despliega la caja de diálogo llamada “Rule Set Editor” la cual nos permite establecer las reglas que componen ese RuleSet, su configuración de encadenamiento o Chaining (el mismo que explicaremos más adelante), su prioridad, su comportamiento de re-evaluación, la expresión condicional, las acciones a ejecutar si esa expresión es verdadera (THEN) y las acciones a ejecutar si esa expresión resulta ser falsa (ELSE). Podemos apreciar esta caja de diálogo en la siguiente figura:

Es tiempo de crear la primera regla de nuestro RuleSet. Hagamos clic en el botón “Add Rule”. Al hacer clic en este botón, es creada una nueva regla con nombre predeterminado “Rule1”. A esta regla le asignaremos una prioridad con valor 100, dejaremos el resto de sus propiedades con el valor por defecto y la condición la expresaremos como “Si a es igual a 20…”, es decir:

Ahora bien, escribamos la expresión para cuando esa condición sea verdadera. Queremos que en el caso que a sea 20, entonces d sea 50: esto lo haremos en la caja de texto para THEN:

Hemos completado la primera regla de nuestro RuleSet. La regla completa la podemos ver en la siguiente figura:

La prioridad de las reglas permite al motor de reglas de Workflow Foundation determinar qué reglas se evalúan primero y cuáles después. En un RuleSet, las reglas serán ejecutadas en el orden del valor de prioridad que tengan asignadas, siendo la regla que tenga el valor más alto la que se evaluará primero y así consecutivamente.

Continuemos ahora agregando una segunda regla a nuestro RuleSet, haciendo clic en el botón “Add Rule” de la barra de botones para crear una regla llamada Rule2. La expresión condicional para esta regla será “Si b es igual a 1, a será 20 de lo contrario d será 90”, de ahí que la condición será:

El bloque THEN:

Y la expresión ELSE:

A esta regla le asignaremos la prioridad con un valor de 99. Agreguemos otra regla llamada Rule3 a nuestro RuleSet con prioridad 98 y con la expresión condicional: “Si d es 50 entonces c es 100 de lo contrario c es 60”. La siguiente figura muestra las reglas Rule2 y Rule3 terminadas:

Muy bien, es hora de poner en marcha nuestro RuleSet y comprobar su funcionamiento, para esto agregaremos una actividad de tipo Code después de la actividad policyActivity1 en nuestro diseñador. Le asignaremos como valor “DisplayResults” en la propiedad ExecuteCode en la ventana de propiedades de esta nueva actividad (codeActivity1). La siguiente figura muestra el diseñador de Workflow Foundation incluyendo esta nueva actividad:

Después de teclear <Enter> Visual Studio .NET nos mostrará el código fuente de nuestro flujo de trabajo y el cuerpo del método DisplayResults(). Completemos el código:

Este código mostrará en la consola el valor de cada una de los campos que creamos.

Ejecutemos el código y veamos el resultado:

¿Por qué los resultados son así? Es muy importante hacer un alto y hacer notar la Dependencia que tienen las reglas Rule1 y Rule2 y Rule 3 entre sí.

Podemos decir que, existe Dependencia entre reglas cuando una regla modifica un campo o propiedad que otra regla está leyendo como parte de su expresión condicional, tal y como sucede en Rule1 y Rule2 en donde Rule1 está evaluando el valor de a y asimismo Rule2 está modificando el valor de a.

Asimismo, Rule3 tiene dependencia tanto con Rule1 y Rule2:

Con Rule1 porque modifica el valor de d cuando su expresión condicional es verdadera (THEN) .

Con Rule2 porque esta modifica el valor de d cuando su expresión es falsa (ELSE).

En este caso específico, el motor de reglas de Workflow Foundation usa el concepto de encadenamiento de reglas o Chaining, para determinar si una regla se re-evalúa como resultado de la modificación de un campo o propiedad que otra regla haya modificado.

Chaining es el proceso en donde el motor de reglas de Workflow Foundation re-evalúa las reglas dependientes entre sí, encadenando efectivamente una con otra hasta que todas las reglas de un RuleSet son evaluadas. Hay tres tipos de Chaining: Implícito, Basado en Atributos y Explícito.

Tipos de Control de Chaining

A continuación se explican cada uno de los tipos de Chaining que el motor de reglas de Workflow Foundation implementa:

Implícito (default)

En este tipo de Chaining el motor de reglas de Workflow Foundation es el responsable de asegurarse que las reglas se evalúen y re-evalúen según sus dependencias entre sí. Este es el mecanismo de Chaining por defecto ya que es el más sencillo de usar para nosotros los desarrolladores ya que el motor de reglas se encarga de todo el proceso de encadenamiento.

Basado en Atributos

Este tipo de Chaining utiliza atributos especiales con los que podemos decorar nuestros métodos para determinar si un campo o propiedad será modificado después de ejecutar dicho método. Este mecanismo es usado para escenarios de Chaining más sofisticados y complejos. Los atributos usados en este tipo de Chaining son los siguientes:

  • RuleRead. Le indica al motor de reglas que un campo o propiedad está siendo leído.
  • RuleWrite. Le indica al motor de reglas que un campo o propiedad está siendo modificado.
  • RuleInvoke. Le indica al motor de reglas que el método especificado será invocado, el cuál muy probablemente esté a su vez decorado con ReadWrite. Este atributo es usado cuando un método ejecuta otro.

Explícito

Este tipo de Chaining hace uso de la cláusula Update, la cual le indica de inmediato al motor de reglas que un campo o propiedad ha sido modificado. Prácticamente este mismo comportamiento lo obtenemos con el Chaining implícito o por medio del atributo ReadWrite, sin embargo este mecanismo es necesario cuando estamos invocando un método o función que no hayamos escrito nosotros en nuestras reglas. Por ejemplo:

Ejemplo

Modifiquemos nuestro proyecto agregando un método llamado Modifica_A() que reciba como parámetro un entero. A este método lo decoraremos con el atributo RuleWrite(“a”) para indicar al motor de reglas que este método está actualizando el valor del campo a. El código es el siguiente:

Asimismo, modifiquemos la acción THEN de Rule2 para invocar el método Modifica_A() enviando como parámetro el valor 20 en vez de hacer la modificación directamente en el código de la acción:

El resultado será el mismo. Ahora quitemos el atributo [RuleWrite(“a”)] del método Modifica_A(). Ejecuta de nuevo el proyecto. ¿Qué sucede?

Tipos de Comportamiento de Chaining

Tenemos la posibilidad de modificar el comportamiento de Chaining para nuestro RuleSet, ya que existen tres tipos de comportamientos los cuales están listados en la siguiente tabla:

Tipo de Comportamiento

Descripción

Encadenamiento Completo (Full Chaining)

Este es el comportamiento por defecto

Solo Actualización Explícita (Explicit Update Only)

Como su nombre lo indica este comportamiento desactiva todos los atributos y el Chaining implícito y únicamente usará las cláusulas Update para llevar a cabo el proceso de Chaining.

Secuencial (Sequential)

Con este comportamiento, el motor de reglas evalúa las reglas una sola vez en el orden indicado por su prioridad.

Debemos tener especial cuidado al seleccionar tanto el tipo de control como el tipo de comportamiento de Chaining, ya que podríamos llegar a una situación de un bucle infinito en donde una Regla A modifique un valor que cause que otra Regla B se evalúe, y esta a su vez modifique un campo que Regla A utiliza.

Ejemplo de Comportamiento Secuencial

Modifiquemos el comportamiento del Chaining en nuestro RuleSet a Sequential. Esto lo podemos lograr en la caja de diálogo “Rule Set Editor” y seleccionando apropiadamente el valor de la lista desplegable. Hagamos clic en el botón OK y otra vez OK. Ejecutemos otra vez nuestro proyecto. El resultado ahora será:

Comportamiento de Re-evaluación

Existen dos tipos de comportamientos de re-evaluación para las reglas dentro de un RuleSet: Siempre (Always) o Never (Nunca).

Always es el comportamiento por defecto en donde la regla se re-evaluará tantas veces como sea necesario según la dependencia y el mecanismo de Chaining. Por el otro lado, Never como su nombre lo indica evaluará solo la primera vez la regla pero nunca se re-evaluará. Podemos hacer uso de este mecanismo para evitar bucles infinitos entre las reglas.

La cláusula Halt

Esta cláusula sirve para terminar la ejecución del RuleSet. La podemos equiparar a la función break dentro de un bucle for de Visual C# ya que nos sirve para regresar el control al código origen cuando cierto objetivo ha sido logrado dentro de nuestro RuleSet y ya no sea necesario ejecutar las demás reglas.

Resumen

En este capítulo profundizamos acerca de las reglas y vimos el uso de la actividad Policy. También se explicó el término RuleSet y vimos en la práctica cómo crean. Posteriormente hablamos del mecanismo de Chaining y sus diversos comportamientos y opciones incluídos en el motor de reglas de Workflow Foundation para resolver escenarios sencillos o más sofisticados en nuestras aplicaciones que necesiten usar este motor.

Este artículo fue creado para el curso Desarrollador .NET de la revista Users.  http://desarrollador.redusers.com/

Otro mapa de México en XAML

Siguiendo la iniciativa que mencioné hace algunos días, mi buen amigo y colega Martín Uresti me pasó otro mapa de la República Mexicano en XAML más detallado y preciso para usarlo en nuestras aplicaciones Silverlight / WPF.  Muchas gracias Martín por tu colaboración y por compartirnos este gran recurso que será sin duda alguna de mucha ayuda para más de una persona.

El mapa lo pueden descargar de La Liga Silverlight en su sección “Contenido” o haciendo clic directamente aquí.

Haz clic en la foto para verla más grande

Espero les sea de ayuda!

Mapa de México en XAML

Acabo de terminar la primer versión del mapa de mi querido país México en versión XAML (de hecho, creo que es el primer mapa de México con sus estados en XAML :) ) para todos aquellos desarrolladores y entusiastas de las tecnologías Silverlight o Windows Presentation Foundation –principalmente mexicanos- que deseen incorporarlo en sus soluciones.  Este mapa puede ser punto de inicio para nuevas y emocionantes interfaces de usuario para brindar a los usuarios de nuestras aplicaciones una mejor experiencia en su uso.  Incluso para aplicaciones didácticas novedosas que deseen mostrar información relacionada con cada estado de la República, o para aplicaciones que necesiten filtrar información para cada estado, etc.  (Atención INEGI) ;) .  Crearlo me llevó algunas horas de trabajo y el uso de diversas herramientas como Expression Design, Photoshop y Expression Blend.

El mapa incluye los 32 estados de la República Mexicana, cada uno implementado en un <Canvas> con el nombre de estado para poder identificarlos apropiadamente cuando deseemos programar algún tipo de comportamiento o funcionalidad en ellos.

Visual Studio .NET 2008 mostrando el mapa de México hecho XAML

Haz clic en la imagen para ver la versión completa

Asimismo, para aquellos desarrolladores que deseen tener un código de ejemplo de cómo podemos utilizar este mapa, aquí les dejo a continuación el código necesario para identificar por medio de un color diferente el estado que esté seleccionado (que esté obteniendo el foco por medio del cursor del mouse):

Y claro está, no olviden modificar la propiedad RootVisual de la aplicación para ejecutar correctamente Mexico.xaml:

El mapa de México en XAML lo pueden descargar aquí

Próximamente estaré escribiendo un artículo de cómo podemos hacer un control reutilizable para Silverlight utilizando este mapa de México hecho XAML.

Espero les sea de utilidad.

Salu2!

Presentando: La Liga Silverlight

Es para mí un verdadero honor y orgullo comunicarles de manera oficial el lanzamiento de La Liga Silverlight:  Un gremio de habla hispana para desarrolladores profesionales y entusiastas acerca de la tecnología Silverlight de Microsoft.  Esta comunidad es el resultado de una serie de ideas y sueños en donde la principal meta es el establecimiento de un gremio no necesariamente reducido a un espacio físico (como sucede con la mayoría de comunidades MSDN) en donde todas las personas interesadas y apasionadas con la tecnología puedan participar y aprender de los demás.  Estamos totalmente convencidos de que todos podemos aprender de todos y que las distancias geográficas deben desaparecer para poder llegar a todas aquellos lugares y rincones del planeta:  y qué mejor que hacerlo ahora que la tecnología nos lo permite de una manera barata y rápida.

La Liga Silverlight es una comunidad 90% virtual y 10% presencial enfocada a discutir, enseñar y aprender todo de Silverlight y sus tecnologías íntimamente ligadas como XAML, Expression Blend y WPF.  A continuación les presento el Manifiesto de La Liga Silverlight para que todos conozcan más acerca de este gremio:

Manifiesto

Somos un gremio auto-organizado y participativo de habla hispana enfocado a la tecnología Silverlight deMicrosoft (y tecnologías íntimamente relacionadas como XAML, ASP.NET, ADO.NET Data Services)

Creemos que la especialización y enfoque en las comunidades y sus contenidos es la única manera de aprender con más detalle cualquier tipo de tecnología

Nuestra comunidad es de origen mexicano, con miras a agrupar a cualquier persona que esté dispuesta a participar en nuestras iniciativas sin importar su nacionalidad o posición geográfica

Creemos que nuestro idioma y pasión por la tecnología son los comunes denominadores para alcanzar nuestros objetivos

Nuestras iniciativas y esfuerzos no tienen fines de lucro y por lo tanto no estamos atados, amarrados, vinculados u obligados con ningún tipo de empresa ni mexicana ni extranjera

La participación de todos sus integrantes es la única manera de producir contenido global y útil para todos

Si bien las reuniones presenciales son importantes, la disponibilidad del contenido y participación en línea son aún más importantes para poder llegar a todas aquellas personas que por su disposición geográfica les es imposible unirse a una reunión física

El tiempo de las personas es lo más valioso que hay, y por ello trataremos que todos nuestros esfuerzos sean para aprender más en menos tiempo, utilizando el tiempo de manera eficaz y eficientemente

Creemos en la privacidad de todos los integrantes y es por ello que toda información personal (como correos electrónicos o nombres) no será distribuida de ninguna manera a terceros con fines de lucro

-La Liga Silverlight

El día de hoy sin duda alguna es un gran día lleno de honor para todos los que conformamos La Liga Silverlight ya que estamos seguros que será un gremio de alta importancia para todos los desarrolladores de Silverlight de habla hispana, y además porque en ella se ve y verá reflejada nuestra pasión por la tecnología y por aprender más de todos y de todas.

Sean ustedes bienvenidos/as a La Liga Silverlight!

– Guadalajara, Jalisco, México, 20 de noviembre 2008

Vínculos y Direcciones

La Liga Silverlight

La Liga Silverlight – Manifiesto

La Liga Silverlight – Preguntas Frecuentemente Preguntadas (FAQ)

La Liga Silverlight – Blogs

La Liga Silverlight – Registro

Salu2!!!

Transportando datos de archivos de texto plano a tablas de SQL Server con BizTalk Server 2006 paso a paso. Parte 2 de 2

Transportando datos de archivos de texto plano a tablas de SQL Server con BizTalk Server 2006 paso a paso. Parte 2 de 2.

Resumen

En la primer parte vimos cómo crear los esquemas necesarios para leer los archivos de texto plano de nuestra tienda.  Vimos también cómo configurar un pipeline de recepción que incluya los esquemas creados para poder desensamblar los archivo correctamente.  En este artículo continuaremos con el escenario y juntaremos todas las piezas del rompecabezas.

Creación de la Orquestación

El siguiente paso es crear la orquestación dentro de nuestro proyecto.  Para realizar esto hagamos clic derecho sobre nuestro proyecto y seleccionemos Add New Item.  A la orquestación le asignaremos el nombre Tienda_Orchestration.odx tal y como lo muestra la siguiente figura:

Ahora necesitamos un puerto de recepción por medio del cuál podamos obtener los archivos de texto plano.  Agreguemos el puerto a la orquestación haciendo clic derecho sobre el area denominada Port Surface y seleccionemos la opción Configured Port.  El nombre del puerto será Tienda_Recepcion:

En la siguiente ventana seleccionemos la opción de crear un nuevo tipo de puerto definiendo el nombre Tienda_Recepcion_Tipo y su tipo de comunicación como One-Way:

En la siguiente ventana seleccionemos la dirección de comunicación de tipo recepción y el port binding a Specify later.  Una vez hecho esto hagamos clic en siguiente y luego finalizar.

El paso anterior creará el puerto de recepción en la orquestación.  A la operación llamada Request del puerto debemos definir cuál será el tipo de mensaje que recibirá.  Seleccionemos Tienda_Album en la propiedad Message Type usando la ventana de propiedades

Agreguemos una actividad de tipo Receive a la orquestación y asignemos su propiedad Activate igual a True.  Su tipo de mensaje será Tienda_Input_Album (consultar la sección “Anexos” en este artículo para más información acerca de los mensajes y variables que deben ser creados) y su operación relacionada será Tienda_Recepcion.Operation_1.Request

Agreguemos una actividad de tipo Construct Message justo debajo de la actividad Receive recién incorporada.  En su propiedad Messages Constructed seleccionemos Tienda_Input_Artista ya que es el tipo de mensaje que deseamos construir.  Además le agregaremos una sub-actividad de tipo Message Assignment para poder construir el mensaje. 

Usando la ventana de propiedades modifiquemos Expression para que tenga el siguiente código:

El anterior código obtiene el artista del archivo recibido (gracias a que ese esquema está definido como header en el pipeline de recepción) y lo guarda en una variable de tipo XmlDocument.  Posteriomente, esta variable es usada para inicializar el mensaje de tipo Tienda_Input_Artista.

Bien, ahora necesitamos agregar un puerto de tipo Send usando la ventana de BizTalk Explorer con las siguientes consideraciones:

  • El tipo de puerto será Static-One-Way
  • Nombre: Tienda_Router_Sql
  • El tipo de transporte será SQL
  • La cadena de conexión deberá configurarse para conectarse a la base de datos Tienda usando el usuario biztalkuser definido en la parte 1 de este artículo.
  • Document Target Namespace: http://tienda.router/sqloutput
  • Response Document Root Element: alb
  • Send Pipeline: PassThruTransmit

Una vez agregado el puerto de tipo Send, hagamos clic derecho sobre la carpeta SPSchema y seleccionemos Add-Add Generated Items… e indiquemos la plantilla Add Adapter Metadata en la caja de diálogo.

Seleccionemos el puerto Tienda_Router_Sql en la siguiente ventana y hagamos clic en el botón Next.

En el siguiente paso del asistente llamado Database Information hagamos clic en el botón Next.  En el siguiente paso definamos los siguientes valores y despúes hagamos clic en el botón Next.

  • Target namespace:  http://tienda.router/sqloutput (el mismo que cuando creamos el puerto de tipo Send)
  • Port type: Send port
  • Request document root element name: alb_request
  • Response document root element name: alb_response

En el siguiente paso seleccionemos la opción Stored Procedure y hagamos clic en el botón Next.  En el siguiente paso seleccionemos InsertaArtista y en seguida hagamos clic en Finish.  Repitamos estos mismos pasos para el procedimiento almacenado InsertaAlbum.

Creación de los mapas de transformación

Hagamos clic derecho en la carpeta Map y seleccionemos la opción Add->New Item… y seleccionemos la plantilla Map de la caja de diálogo.  El nombre del mapa será Tienda_Artista.btm.

Seleccionemos el data source del esquema origen a Tienda_Artista:

Seleccionemos el data source del esquema destino a SqlService_sqloutput.  A continuación, seleccionemos alb_request como root node.  Realicemos el mapeo necesario tal y como lo muestra la siguiente figura:

Agreguemos una nueva actividad de tipo Construct Message a la orquestación y dentro de ella una actividad de tipo Transform.  Hagamos doble clic sobre Transform_1 y configuremos de la siguiente manera la transformación:

  • Existing Map
  • Fully Qualified Map Name: Tienda.Map.Tienda_Artista
  • Source: Tienda_Input_Artista
  • Destination: Tienda_Output_Artista

Agreguemos una actividad de tipo Send a la orquestación y le asignamos su propiedad Message a Tienda_Output_Artista.

Agregar un nuevo puerto de envío a la orquestación haciendo clic derecho sobre el Port Surface del diseñador con los siguientes parámetros:

  • Name: [Empresa]_Envio_Header
  • Tipo: [Empresa]_Envio_Header_Tipo
  • Comunicación: One-Way
  • Dirección: Send
  • Binding: Especificar después

Configurar su operación llamada Request con la propiedad Message Type como Tienda.SQLService_sqloutput.alb_request.  Una vez hecho esto, conectamos el shape Send_1 al nuevo puerto tal y como lo muestra la siguiente figura:

Repitamos los pasos anteriores para el mensaje Tienda_Output_Album.

Podemos usar una actividad de tipo Parallel para que el envío del artista junto con sus albumes relacionados sea al mismo tiempo en vez de secuencial.

Deployment

Como último paso debemos hacer Deploy de nuestro proyecto haciendo clic en la opción Deploy del menú Build de Visual Studio .NET.

Una vez hecho el deployment debemos configurar los puertos de recepción y envío usando la herramienta BizTalk Server 2006 Administration Console haciendo clic derecho sobre la orquestación en la lista de aplicaciones.

  • El pipeline del puerto de recepción debe ser de tipo Tienda_ReceivePipeline
  • El puerto de recepción debe tener relacionado un folder que tenga el suficiente nivel de permisos de acceso para poder leer los archivos (en este demo se agregó Everyone Full Control a un folder llamado C:\Archivos)
  • El filtro para el puerto de recepción debe ser *.txt
  • Configurar adecuadamente el polling interval. En esta demo se configuró a 15 segundos (15000 ms)
  • El puerto de envío debe ser de tipo SQL y su pipeline de tipo PassThruTransmit
  • El puerto de envío debe tener configurada la cadena de conexión correcta para poder ejecutar los stored procedures relacionados

Lo último que resta es iniciar la orquestación haciendo clic sobre ella y seleccionar la opción Start del menú contextual.  Para probar, copiemos un archivo de texto a la carpeta en donde se configuró el puerto de recepción y listo!  Nuestras tablas son actualizadas correctamente en SQL Server.

Anexos
Mensajes

Nombre del mensaje
Tipo

Observaciones

Tienda_Input_Artista
Tienda.FFSchema.Tienda_Artista

Creado por medio del Flat File Schema Wizard

Tienda_Input_Album
Tienda.FFSchema.Tienda_Album

Creado por medio del Flat File Schema Wizard

Tienda_Output_Artista
Tienda.SQLService_sqloutput.alb_request

Creado por medio de la opción Add Adapter Metadata (cambiar el nombre apropiadamente por medio de la ventana de propiedades si es que ya existe un archivo con el mismo nombre)

Tienda_Output_Album
Tienda.SQLService_sqloutput_1.alb_request

Creado por medio de la opción Add Adapter Metadata (cambiar el nombre apropiadamente por medio de la ventana de propiedades si es que ya existe un archivo con el mismo nombre)

Variables

Nombre de la variable
Tipo

headerDocString
String

headerDocXml
System.Xml.XmlDocument

Conclusión

BizTalk Server 2006 es una poderosa herramienta para la integración entre aplicaciones incluso de diferentes plataformas.  En este artículo dividido en dos partes vimos cómo enviar los datos de archivos de texto planos a tablas de SQL Server por medio de una orquestación de BizTalk Server 2006.

Transportando datos de archivos de texto plano a tablas de SQL Server con BizTalk Server 2006 paso a paso. Parte 1 de 2

No es raro hoy en día encontrarnos con aplicaciones que integran datos de diferentes plataformas para obtener la información necesaria y poder explotarla adecuadamente.  Son bastantes los escenarios que nos podemos encontrar como consultores en los que determinada empresa cuenta ya con un sistema de tipo legacy y que debido a su gran importancia histórica es imposible tirarlo a la basura incluso resultaría bastante caro y arriesgado adentrarse en el largo y sinuoso camino de la migración total -incluso parcial- de su código a una plataforma moderna y escalable como es .NET.  Por lo anterior es muy común que las empresas requieran de alguna forma u otra seguir obteniendo o procesando los datos que sus sistemas legacy arrojan y a la vez renovar su plataforma y arquitectura tecnológica a nuevos horizontes. 

Así que, en este artículo aprenderemos a procesar archivos de texto planos para leer su contenido y posteriormente escribirlo a tablas de SQL Server 2005 por medio de una orquestación de BizTalk Server 2006.  Una vez terminado de leer este artículo podrán apreciar lo sencillo que puede ser esta tarea al ser coordinada y procesada con esta magnífica pieza de software.

El escenario

Nuestro sistema legacy es un sistema de compras e inventarios de una cadena de gran importancia a nivel nacional de venta de discos compactos musicales.  No obstante, la empresa requiere que el catálogo de discos sea replicado a una base de datos de SQL Server 2005 por medio de una orquestación de BizTalk Server 2006 una vez que un nuevo título llegue a su inventario.

El sistema legacy escribirá un archivo de texto plano con extensión .txt por artista una vez que nuevos álbumes lleguen al inventario.  El archivo de texto plano tendrá el siguiente esquema:

ARTISTAID | NOMBRE | GENERO

ARTISTAID | ALBUMID | TITULO_DEL_ALBUM | ANIO | CANTIDAD

ARTISTAID | ALBUMID | TITULO_DEL_ALBUM | ANIO | CANTIDAD

ARTISTAID | ALBUMID | TITULO_DEL_ALBUM | ANIO | CANTIDAD

Con lo anterior podemos deducir que en un solo archivo podrán incluirse diferentes albumes del mismo artista.  Además, podemos observar que los archivos incluyen el pipe (|) como separador de cada atributo.

Por otro lado, tenemos una base de datos de SQL Server 2005 llamada Tienda la cual cuenta con las tablas Artista y Album que son donde se depositarán los datos de los archivos de texto plano y su esquema es el siguiente:

La solución

La solución está basada en una orquestación implementada con BizTalk Server 2006 la cual será capaz de detectar la existencia de un nuevo archivo y procesará su contenido apropiadamente para escribir los datos en las tablas del servidor de SQL Server 2005.

Para iniciar, implementemos los procedimientos almacenados encargados de escribir los datos en las tablas de la base de datos.  Los procedimientos almacenados serán llamados spInsertaArtista y spInsertaAlbum para las tablas Artista y Album respectivamente y su código es el siguiente:

También necesitamos un login de SQL para poder conectarnos a SQL Server 2005 desde BizTalk y poder ejecutar los procedimientos almacenados.  Claro está que será más recomendable usar autenticación de tipo Windows en vez de usar usuarios de tipo SQL pero para este artículo lo dejaremos así.  La cuenta que crearemos será biztalkuser con el password Pa$$W0rd y le asignaremos el rol de dbo_owner sobre la base de datos Tienda:

Muy bien, tenemos los elementos básicos para comenzar.  Lo primero que vamos a hacer es abrir Visual Studio .NET y crearemos un nuevo proyecto de tipo Empty BizTalk Server Project y le pondremos el nombre Tienda, tal y como lo muestra la siguiente figura:

Una vez creado nuestro proyecto es buena idea cambiarle las propiedades Application Name y Restart Host Instances para poder identificar nuestra aplicación en la consola de administración de BizTalk y para reiniciar todas las instancias cuando despleguemos el proyecto respectivamente.  La siguiente figura muestra las propiedades de nuestro proyecto:

Por efectos de orden y limpieza en nuestro proyecto crearemos los siguientes fólders:

Nombre
Descripción

FFSchema
Aquí guardaremos los esquemas para el pipeline que lee los archivos de texto planos

Map
Aquí guardaremos los mapas de transformación

Pipeline
Aquí guardaremos los pipelines de recepción para los archivos de texto planos

SPSchema
Aquí guardaremos los esquemas necesarios para ejecutar los procedimientos almacenados en SQL Server 2005

Creación de los esquemas

El siguiente paso será la creación de los esquemas apropiados para interpretar el esquema de los archivos de texto plano.  Para el tipo de archivo que procesaremos en este ejemplo crearemos dos esquemas: uno para el header que contiene información básica del artista y otro para el detalle el cual como mencionamos anteriormente puede contener uno o varios albumes del mismo artista.  Los siguientes pasos muestran la creación del esquema para los álbumes, sin embargo serán los mismos pasos para la creación del esquema para el artista.  Para hacer esto agreguemos al fólder FFSchema un nuevo elemento de tipo Flat File Schema Wizard y asignemos el nombre Tienda_Album.xsd tal como lo muestra la siguiente figura

Al hacer anterior Visual Studio nos muestra el asistente de creación de esquemas para archivos de texto planos.  En la primer ventana asignaremos un archivo muestra de los cuales necesitamos procesar y asignaremos algunos parámetros como Record name y Target namespace.  La siguiente figura da ejemplo de esto:

La siguiente tarea será seleccionar las líneas en el archivo de texto que representan el detalle tal y como lo muestra la siguiente figura:

Hagamos clic en siguiente para aceptar la opción “By delimiter symbol”.  La siguiente ventana nos solicita indicar el delimitador para cada registro, en nuestro caso será el default {CR}{LF} ya que cada registro está indicado en una línea por separado.  La siguiente figura muestra esta ventana:

Al hacer clic en el botón Siguiente en la ventana anterior se nos muestra la opción de indicar cuáles son los elementos hijos.  En el caso específico de este ejemplo seleccionaremos el primer registro como Repeating record y le asignaremos el nombre Album mientras que al resto de registros les asignaremos el tipo Ignore ya que son exactamente iguales que el primero en estructura.  La siguiente figura muestra los elementos configurados:

La siguiente ventana nos muestra un resumen del esquema, sin embargo aun falta terminar de configurar los registros así que haremos clic en siguiente.  La siguiente ventana llamada “Select Document Data” nos solicita seleccionar los datos que definen un registro dentro del archivo de texto plano.  De manera predeterminada el asistente es lo suficientemente inteligente para seleccionar el registro tal como lo muestra la siguiente figura, posteriormente haremos clic en Siguiente.

Tal y como hicimos anteriormente, en la ventana “Select Record Format” aceptaremos la opción “By delimiter symbol” y haremos clic en el botón Next.

Ahora se nos presenta de nueva cuenta la ventana “Delimited Record”, en ella especificaremos en la lista desplegable llamada “Child delimiter” el caracter que delimita cada columna dentro de nuestro archivo en este caso se trata del pipe (|).  Al hacer clic en el botón Next se nos muestra la siguiente ventana en donde podemos definir el nombre de cada elemento (columna) que representa un registro de cada álbum:

Al hacer clic en siguiente se nos presenta el resumen del esquema y para terminar haremos clic en el botón Finish.

Una vez terminada la creación del esquema modificaremos la propiedad Element FormDefault del nodo <Schema> para tener el valor “Qualified”:

No olvidemos el esquema para el Artista!  Sigamos todos los pasos anteriores que usamos para crear el esquema de los álbumes con la única diferencia que a la propiedad Max Occurs en Artistas/Artista le asignaremos un valor de 1.

Creación del Pipeline de recepción

Nuestra siguiente tarea será la creación del pipeline de recepción para nuestro proyecto.  Para hacer esto agreguemos un nuevo elemento de tipo Receive Pipeline dentro de nuestro fólder Pipeline y asignemos el nombre Tienda_ReceivePipeline.btp tal como lo muestra la siguiente figura:

Para diseñar nuestro pipeline usaremos el componente Flat file disassembler y lo colocaremos en la sección “Disassemble” del diseñador la cual permite indicar la funcionalidad a ejecutar cuando queremos desensamblar nuestro archivo.  Además le asignaremos las propiedades Document schema y Header schema a Tienda_Album y Tienda_Artista respectivamente, además de poner en True la propiedad Preserve header.  La siguiente figura muestra el componente Flat file dissasembler configurado:

Wuf! Vamos muy bien pero aún falta camino por recorrer.  La segunda parte de este articulo explicará la orquestación de BizTalk y demostrará cómo todas las piezas de este rompecabezas se unen.

How to be a better developer?

This is the english version of my “¿Cómo ser un mejor desarrollador?” article

Maybe we have asked this question to ourselves a bunch of times.  With so many technologies, acronyms and learning options available today it seems that the answer to this question is not as easy as it seems.

Maybe so many of you will respond right now: “Studying” or “Taking a Training Course”, but: Is that enough?

Here’s the list of things that -in my personal life- I try to do in order to be a better developer.  The main idea behind the following list is to enrich it with your ideas and collaboration.

I don’t know anything

Why?  This is the most important start point and the most critic because the fundamental idea -like in any other learning process- is to recognize and accept our ignorance in so many and so huge topics and technologies.  Take off our egocentrism allows us to open our mind to other kind of knowledge and other kind of questions.  After all, we learn something from everyone each day.  Remember that monotony is the mother of mediocrity.

Listen to PodCasts

Why?  You can listen to the podcast at any time you want using your iPod, Zen, Zune, etc. in your car, at the office, at the gym, before sleep (please… BEFORE sleeping not WHILE YOU ARE sleeping ;) ), etc.  I mean: you can stay in contact with the specific topic whenever you want and you can combine it with another kind of activity (please be careful when driving because you couldn’t say to the officer “I’m so sorry, I’ve crashed the car because I was listening how to create a workflow in WF…”).  But which ones?  Alright take these as a recommendation: Scott Hanselman’s Hanselminutes and Ron Jacobs’ ArCast.  In these podcasts you can listen to so many topics about recent and upcoming technologies and in the other hand they are fun!  Those guys really know what they’re talking about…seriously.

Watch WebCasts

Why? I like Webcasts because they show and explain visually a specific topic; meanwhile the podcasts are audio-only.  But which ones?  I recommend: http://www.microsoft.com/events/default.mspx

Watch ScreenCasts

Why? A ScreenCast is a small video file that shows an specific technology topic in a “how-to” way.  They just are awesome knowledge sources because they teach us how to perform the required tasks for the problem we’re trying to resolve.  But which ones?  Obviously, it depends on the technology we’re using.  What about the ASP.NET, AJAX, Silverlight and Workflow Foundation as a startup?

Forum Participation

Why?  The forums are a basic resource when we have a specific doubt related to technology.  With the word Forum I refer to those Web-based and Newsgroups as well.  Also we have the opportunity to answer the questions of any other people in the world that has a problem and maybe you know how to fix it.  But which ones?  Each technology has its own forum.  Personally, I often visit the Workflow Foundation and Silverlight ones.

User groups meetings / Community meetings

Why?  There’s no better way of learning from others but in person, front to front about an specific topic.  That’s what .NET User Groups are for, to schedule meetings between different people geographically related in order to talk and show the technology.  But which ones?  There’s always a .NET User Group near you.  Visit MSN Groups to find more information about it.

Read Books

Why?  The answer is obvious.  Books are an ancient source of any kind of knowledge (hundreds and hundreds of years of manual and automatic printing can’t be wrong).  But which ones?  Personally, I like Programmer-To-Programmer books from Wrox (yeah, the red ones).  Another great development books are Microsoft .NET Development Series books because they are written by truly experts.

Read Blogs

Why? A web log is a personal log from other’s ideas, thoughts and technical articles from its author and it’s accessible via Web.  A good example is this blog where I’m writing my own opinions in how to be a better developer.  Is this The Ultimate Special Platinum Double-Pack Director’s Cut Extended Anniversary Edition Article about it?  Of course not! And it’s not meant to be like that tho.  It’s just a way to synthesize what I do in order to be a better developer and it’s a mechanism to share it and to obtain feedback about it.  But which ones?  I could write down here all my feeds but I’ll just write the ones that I read day by day:

ScottGu
Soma
Silverlight
Eric Sink
Joel on Software
Erika Ehrli

Learn to use other technologies

Why? Yes. We are geeks.  And we love Microsoft development technologies, but we would be blind or crazy if we wouldn’t recognize that there’s a bunch of other excellent technologies and that not everyone in this world use the same tools as we do.  In the other hand, they’re not absolutely necessary to be non-Microsoft technologies.  For example, IronRuby is a technology that I don’t know how to use it but it seems to me very powerful and interesting enough to try to learn from it.  But which ones?  There’s a lot right in front of our eyes.  For example I’m currently using and learning ActiveRecord.  Other technologies in my “To-Learn” list are: IronRuby, IronPython, F#, Microsoft Sync Framework and ASP.NET MVC Framework.

Adopt a Development Methodology

(Very special thanks to Misael for this one)

Why?  A methodic person has more control over the things he performs, and he can identify where he is and what step follows in his development path:  Identify, Measure, Document, Secure and Control are steps that can be reached using the correct methodology.  But which ones? There are so many methodologies but the must important could be the following:

Do not procrastinate

Why?  Up to this point, we have mentioned a list of learning resources that we can use in order to be better developers.  But we need the tactics and strategy, and these are of course: Discipline.  We need a great effort and discipline in order to accomplish our goal and to stop using and doing the things that waste our time.  YouTube, FaceBook, MSN Messenger are just a few of those things that come to my mind right now.  No excuses (like Alice in Chains once said) please.  Remember how we worked 10 years ago.  Let’s measure our procrastination level:  If you think this is a very drastic solution then you have a very serious procrastination problem.  But, if you are willing to stop wasting your time (you know you do!) then: Congratulations, your procrastination problem can be cured.

Try to hang up with people that love software development

At last but not least, it’s very important to look for people that are just as restless as you are and have the same learning goals (please refer to point number one).  Once you find them then it will be very helpful to talk and chat with them, and get support from them in your process of personal improvement.  That process would be less painful and more fun!

This article was not meant to be a meme but I would like for this topic that the following people could share their own thoughts and ideas:

Publicando Flujos de Trabajo de Workflow Foundation como Servicios Web

Una de las características más novedosas y útiles que podemos encontrar al desarrollar flujos de trabajo con Workflow Foundation es su capacidad de exponer nuestros flujos como servicios Web y usarlos en cualquier tipo aplicaciones. En este capítulo veremos qué se requiere para realizar esta funcionalidad y también veremos cómo invocar nuestros flujos de trabajo como servicios Web desde una aplicación de consola.

Para iniciar, abramos Visual Studio .NET si es que no está ejecutándose ya y creemos un nuevo proyecto de tipo consola haciendo clic en la opción New Project y seleccionando la plantilla Console Application de la categoría Windows. A esta aplicación le asignaremos el nombre AplicacionCliente y nos servirá para invocar el web Service que expondrá la funcionalidad del flujo de trabajo. La siguiente figura muestra la caja de diálogo New Project al crear nuestro proyecto:

A la solución agregaremos un nuevo proyecto de tipo Sequential Workflow Library haciendo clic derecho sobre la solución en Solution Explorer y seleccionando la opción Add->New Project. En la caja de diálogo seleccionemos la plantilla Sequential Workflow Library de la categoría Workflow y asignemos “WorkflowEjemplo” como nombre. La siguiente figura muestra la creación de este proyecto:

Ahora bien, necesitamos definir una interface la cual nos servirá para establecer el conjunto de métodos que nuestro servicio Web expondrá. Para realizar esto hagamos clic derecho sobre el proyecto WorkflowEjemplo en Solution Explorer y seleccionemos la opción Add->New Item del menú. Al hacer esto Visual Studio .NET despliega la caja de diálogo Add New Item con una serie de plantillas a escoger y una caja de texto para asignar el nombre del nuevo elemento. Seleccionemos la plantilla Interface del panel derecho y asignemos “IEjemplo.cs” como nombre de la nueva interfaz. La siguiente figura muestra la caja de diálogo Add New Item al agregar el nuevo elemento:

Al hacer clic en Ok Visual Studio .NET nos muestra el diseñador de código de la interfaz agregada. Asignemos el siguiente código en IEjemplo.cs:

Una vez definida la interfaz para nuestro servicio Web, regresemos al diseñador del flujo de trabajo y arrastremos y coloquemos una actividad de tipo WebServiceInput, la cual indica al flujo de trabajo que obtendrá una solicitud externa a través de una aplicación, es decir, que será invocado como un servicio Web. La actividad WebServiceInput debe ser configurada, siendo su propiedad InterfaceType su propiedad más importante. Esta propiedad indica el tipo de interfaz relacionada con esta actividad y para este ejemplo usaremos la interfaz IEjemplo creada en los párrafos anteriores. Para asignar la interfaz IEjemplo a la propiedad InterfaceType hagamos clic en el botón con tres puntos “…” en la ventana de propiedades de Visual Studio .NET. Al hacer clic sobre ese botón se despliega la siguiente caja de diálogo:

En esta caja de diálogo seleccionemos la interfaz WorkflowEjemplo.IEjemplo (la cual es la única interfaz en nuestro proyecto) y hagamos clic en el botón Ok.

La siguiente propiedad que debemos configurar es MethodName, la cuál como podemos deducir será RegresaSignoZodiacal. Al seleccionar este método de la lista desplegable automáticamente la ventana de propiedades se actualiza para mostrarnos fechaNacimiento en la lista. Esta nueva propiedad la debemos mapear a un campo o propiedad en nuestro flujo de trabajo para tener acceso al dato pasado como parámetro cuando se esté invocando este servicio Web. Seleccionemos la propiedad fechaNacimiento y hagamos clic en la opción “Bind Property ‘fechaNacimiento’” en el panel de opciones de la parte inferior de la ventana de propiedades y en la caja de diálogo generemos un nuevo miembro de tipo campo llamado fechaNacimiento tal y como lo muestra la siguiente figura:

La última propiedad que configuraremos de la actividad WebServiceInput será IsActivating la cual indica si esta actividad activará el flujo de trabajo.

Agreguemos ahora una actividad de tipo IfElse a nuestro diseñador, y como expresión condicional en la rama izquierda asignemos un Code Condition llamado EsFechaValida. Este método validará que la fecha que asigne el usuario como parámetro no sea mayor que la fecha actual. El código entonces para este método será el siguiente:

Como paso siguiente agreguemos una actividad de tipo Code en la rama izquierda de la actividad IfElse y una actividad de tipo WebServiceOutput. A la actividad Code le asignaremos en su propiedad ExecuteCode el método CalculaSigno, y a la actividad WebServiceOutput le asignaremos en su propiedad InputActivityName el nombre de nuestra actividad WebServiceInput (webServiceInputActivity1). Al hacer lo anterior la ventana de propiedades se actualiza para mostrarnos una nueva propiedad llamada ReturnValue. Esta propiedad la mapearemos a un nuevo miembro de tipo field llamado resultado.

En la rama derecha de la actividad IfElse arrastraremos y colocaremos una actividad de tipo WebServiceFault con su propiedad InputActivityName mapeada a webServiceInputActivity1 y su propiedad fault a un nuevo miembro de tipo field llamado fault.

La siguiente figura muestra todo el flujo de trabajo configurado e implementado:

El siguiente código muestra el método CalculaSigno el cuál contiene una implementación muy sencilla para calcular el signo zodiacal según la fecha especificada en el parámetro:

Visual Studio .NET nos brinda una manera muy sencilla de exponer nuestros flujos de trabajo como servicios Web: simplemente hagamos clic derecho sobre el proyecto del flujo de trabajo y seleccionemos la opción “Publish as Web Service”. Al hacer esto Visual Studio .NET creará automáticamente un proyecto Web en nuestra solución el cual contiene el servicio Web que expone la funcionalidad del flujo de trabajo.

Finalmente, en la aplicación de consola agreguemos la referencia Web apuntando al proyecto que se creó en el párrafo anterior y en el método Main() escribamos el siguiente código:

Al ejecutar nuestra aplicación y escribir una fecha válida (que sea igual o anterior a la fecha actual), nos mostrará el signo zodiacal relacionado con la fecha especificada tal y como lo muestra la siguiente figura: