martes, 27 de agosto de 2013

Importancia DateTimeKind en escenarios de intercambio XML II

Hace un tiempo en

areaTIC

publicamos un articulo sobre un caso curioso al intercambiar

XML

mediante

soap

contra otro servidor (java) desde .NET.

Hasta ese momento sólo había tenido problemas con el tipo DateTime? (nullable), pero hoy revisando unos temas he visto que hay más casos donde hay que ir con cuidado y especificar bien la zona horaria para evitar problemas.

Veamos otro ejemplo diferente al nullable:
DateTime fechaDesde = new DateTime(2013, 08, 27, 15, 0, 0);
DateTime fechaHasta = DateTime.Now;
Al serializar estos valores el resultado es el siguiente (son las 17:15):
<fechaDesde>2013-08-27T15:00:00</fechaDesde>
<fechaHasta>2013-08-27T17:15:00.6152148+02:00</fechaHasta>
Yo me encuentro en la zona Central Europea (BCN) por eso concatena un +2:00 correspondiente a la zona horaria en la fecha Hasta, pero en la fecha desde no especifica zona horaria por lo que si no está controlado en servidor seguramente recibirá el valor "17:00" (Utc) en vez de "15:00" como quería enviar.

En cambio si definimos la fechaDesde de este modo ya estaríamos especificando el formato ok y el servidor lo procesará bien.
DateTime fechaDesde = new DateTime(2013, 08, 27, 15, 0, 0,DateTimeKind.Local);
DateTime fechaHasta = DateTime.Now;
Al serializar estos valores el resultado es el siguiente (son las 17:15):
<fechaDesde>2013-08-27T15:00:00+02:00</fechaDesde>
<fechaHasta>2013-08-27T17:15:00.6152148+02:00</fechaHasta>
A la inversa también estaba teniendo problemas, es decir asumía que toda petición que me llegaba vía

soap/xml

me venía en formato "Local" con lo que estaba provocando un desfase importante al notificar esa fecha. Por ejemplo suponeros el caso que una tercera parte involucrada espera esa fecha que recibes en un fichero de texto con formato "yyyy/MM/dd" y yo recibo "19/08/2013 23:00 Z" (donde z es equivalente a Utc o no especificar zona horaria). En este caso notificaríamos como fecha "2013/08/19". Si el servidor me hubiese notificado la fecha en formato "local" hubiese recibido como valor "20/08/2013 00:00 +02:00" y por tanto la fecha a notificar al tercero difiere de un día.

Conclusión, es importante pactar el valor de zona horaria que cada parte va a utilizar y en caso que no sea posible tenemos que obligarnos a que cada vez que recibamos una fecha por este sistema de intercambio controlar el formato y convertirlo en caso que sea necesario. A continuación un ejemplo (se debería controlar más formatos pero es por hacernos una idea):
if (fecha.Kind == DateTimeKind.Utc)
    fecha = TimeZoneInfo.ConvertTimeFromUtc(fecha,TimeZoneInfo.Local);
Hasta aquí el artículo de hoy, recordar que podéis seguir

areaTIC

en las redes sociales. Esperamos tu participación!

martes, 20 de agosto de 2013

Conexión DDE entre .NET y VB6

El artículo de hoy trata sobre un tema un poco desfasado en el tiempo pero que puede resultar útil en compañías donde todavía se trabaje con aplicaciones desarrolladas en VB6 o similares. En realidad nuestra necesidad surge de comunicar una aplicación VB6 contra una centralita telefónica teniendo en cuenta que ya tenemos desarrollada este tipo de comunicación en las aplicaciones .NET de la compañía.

Tal vez podríamos haber optado por publicar un servicio REST en .NET y crear un cliente desde VB6, pero teniendo en cuenta que la aplicación .NET que comunica con la centralita es de escritorio, la solución implicaba tener que montar un servidor web... a parte la comunicación tiene que ser bidireccional por lo que sólo se me ocurre tener que estar haciendo peticiones constantemente a ver si el servidor tiene novedades para el cliente lo cual resulta de todo menos óptimo. También barajamos extraer las funcionalidades de la dll que conecta con la centralita y hacerla interoperable COM pero tras varias pruebas descartamos esa solución (...) por resultar un auténtico curro y engorro hacer la dll interoperable con todos sus tipos y clases.

Tal vez la mejor solución que se nos ocurre a la mayoría es tirar la aplicación VB6 a la basura y rehacerla en .NET jajjaja, pero fuera bromas, en este escenario no es posible así que decidimos probar con una comunicación

DDE

entre las aplicaciones. El resultado es que en unas horas teníamos implementada la comunicación sin conocer a fondo el protocolo y sin perder demasiado tiempo. De hecho sólo hemos implementado un par de funcionalidades, llamar a un número desde VB6 (VB6 a .NET) y avisar a la aplicación de VB6 que tiene una llamada entrante (.NET a VB6).

Resumiendo, ambas aplicaciones han de asumir el rol de servidor o cliente en determinados momentos. A continuación intento reproducir los pasos que han sido necesarios para desarrollar este tipo de comunicación.

En primer lugar comentar que .NET no soporta protocolo

DDE

, aquí os paso un dll de CodePlex con un proyecto desarrollado por terceros a través del cual podemos trabajar con este protocolo en aplicaciones .NET. Una vez descargamos el proyecto nos quedamos con el archivo NDde.dll y lo agregamos como referencia a nuestro proyecto .NET.

.NET a VB6

  • Servidor (VB6):

    En nuestro caso necesitamos pasar a VB6 una cadena de texto a la que la aplicación reaccionará abriendo un formulario de aviso con los datos de la persona que está llamando. Tenemos un formulario principal en esta aplicación por lo que sólo ha sido necesario modificar las propiedades "LinkTopic = 'AreaTICTopic'" y "LinkMode = 1-Source del Form. Si implementamos el evento "Form_LinkExecute(CmdStr As String, Cancel As Integer)" del formulario ya tenemos el servidor VB6 listo para recibir comandos desde .NET.

  • Cliente (.NET):

    Os paso el código necesario para enviar un comando al servidor Vb6.
    using (DdeClient client = new DdeClient("NombreAppVisualBasic", "AreaTICTopic"))
    {
       client.Connect();
       client.Execute(string.Format("Llamada entrante del número {0}", pTelefono), 60000);
       client.Disconnect();
    }
    

VB6 a .NET

  • Cliente (VB6):
    Private Sub cmdLlamar_Click()
        'llamar a DDE .NET informando número de teléfono
        txtnumero.LinkMode = vbLinkNone
        txtnumero.LinkTopic = "AreaTICDDEServer|CallFromVB"
        txtnumero.LinkMode = vbAutomatic
        txtnumero.LinkExecute txtnumero.Text
    End Sub
    
  • Servidor (.NET):

    Tenemos que crearnos una clase AreaTICDDEServer la cual implemente la clase abstracta "DDeServer" y sobreescribiremos algunos métodos para controlar los comandos que nos llegan desde el cliente. Ya digo no he invertido demasiado tiempo en conocer el protocolo así que si queréis indagar más vale que miréis a fondo los ejemplos de codeplex porque hay varios métodos más en la clase abstract que tal vez os interese implementar... lo mío era salir del paso. Los eventos OnError y OnLlamada son opcionales es tema de como organizo el código para no tener que mezclar esta clase con la otra que realiza la llamada lo gestiono con eventos y delegados.
    namespace AreaTIC.DDE
    {
        public sealed class AreaTICDDEServer : DdeServer
        {
            public AsteriskDDEServer(string service)
                : base(service)
            {
            }
    
            public event EventHandler OnError;
            public event EventHandler OnLlamada;
    
            public override void Register()
            {
                base.Register();
            }
    
            public override void Unregister()
            {
                base.Unregister();
            }
    
            protected override bool OnBeforeConnect(string topic)
            {
                try
                {
                    if (!Enum.IsDefined(typeof(Topics), topic))
                    {
                        throw new Exception("No se reconoce el valor de 'Topic' de la conexión entrante");
                    }
    
                    return true;
                }
                catch (Exception ex) 
                {
                    this.OnError(this, new DDEErrorEventArgs(ex));
                    return false;
                }
            }
    
            protected override ExecuteResult OnExecute(DdeConversation conversation, string command)
            {
                if (!Enum.IsDefined(typeof(Topics), conversation.Topic))
                {
                    throw new Exception("No se reconoce el valor de 'Topic' de la conexión entrante");
                }
                else 
                {
                    Topics topic = (Topics)Enum.Parse(typeof(Topics), conversation.Topic);
                    switch (topic) 
                    { 
                        case Topics.CallFromVB:
                            this.OnLlamada(this, new CallEventArgs(command));
                            break;
                    }
                }
    
                // Tell the client that the command was processed.
                return ExecuteResult.Processed;
            }
        }
    
        public enum Topics
        {
            CallFromVB,
        }
    
        public class DDEErrorEventArgs : EventArgs 
        {
            public DDEErrorEventArgs(Exception pex) 
            {
                ex = pex;
            }
    
            public Exception ex { get; set; }
        }
    }
    
    Para iniciar el servidor DDE desde .NET sería necesario este código.
        AreaTICDDEServer mDDEserver = new AreaTICDDEServer("AreaTICDDEServer"); 
        mDDEserver.Register();
        mDDEserver.OnLlamada += this.Llamar;
        mDDEserver.OnError += this.ErrorDDE;
    
Con este ya tendríamos implementada una comunicación

DDE

entre las 2 aplicaciones capaz de intercambiar comandos entre ambos procesos. Hasta aquí el artículo de hoy, recordar que podéis seguir

areaTIC

en las principales redes sociales y no os cortéis a comentar, preguntar o valorar las publicaciones!

martes, 13 de agosto de 2013

BI: Herramientas open source

Si precisamos analizar los datos, información, conceptos,... de una organización para facilitar la toma de decisiones sin duda hemos de pensar en la implantación de una herramienta de BI (Bussiness Intelligence). ¿Qué es una herramienta de BI? Es una herramienta que mediante un proceso ETL (Extract, Transform and Load) obtiene datos de distintas fuentes, los prepara y carga en una estructura de datos (DW, Data Warehouse). A partir de esta información y mediante la creación de cuadros de mando, informes, simulaciones... la herramienta de BI facilita el proceso de toma de decisiones en la organización.

En este artículo os indicaré las que en mi opinión son las herramientas de BI open source más utilizadas, serían las siguientes:

  • Sin duda Pentaho es una de las herramientas de BI open source más conocidas y con uso más extendido. Desarrollada en java y disponible para entornos Windows / Linux /Mac nos ofrece utilidades para creación de procesos ETL, cuadros de mando, informes, integración con otras aplicaciones vía Web Services,... En su web podéis acceder a una demo online (previo registro), a la sección de descargas así como información de las distintas versiones disponibles (existe la open source y las de pago, Professional y Enterprise).


  • Palo es la versión open source community edition de la herramienta de BI Jedox. Palo Suite nos ofrece herramientas de ETL, motor OLAP y interfaz web que nos permiten carga de datos, análisis, integración con Excel, gestión de infomes, gestión de usuarios,... En cuanto a los cuadros de mando, no hay un componente específico para realizarlos pero pueden hacerse utilizando su integración con Excel. En su web podéis acceder a una demo online (no requiere registro), a la sección de descargas así como información de las distintas versiones disponibles como sus características, Palo la versión open source y Jedox la comercial.


  • Jaspersoft además de estar tras la conocida herramienta open source para la generación de informes JasperReports también dispone de una herramienta open source de BI que está construida sobre su motor de reports. Está desarrollada baja arquitectura J2EE lo que la hace fácilmente extensible y personalizable. Dispone de procesos ETL, gestor de informes, cuadros de mando,...Para los procesos de ETL utiliza Talend (con sus pros y sus contras). En su web podéis acceder a una demo online (previo registro), a la sección de descargas así como información de las distintas versiones (Community, Express, Professional y Enterprise). Importante destacar también que se ofrece la herramienta en modalidad SaaS a través de AWS.


    En su web podemos acceder a todos los detalles de esta herramienta open source de BI así como a los foros, wikis, documentación que va generando la comunidad que hay tras ella.

  • SpagoBI es otra herramienta open source de BI desarrollada bajo plataforma J2EE y arquitectura MVC. Dispone de herramientas ETL, cuadros de mando, generación de informes, análisis y gestión de datos,... En su web podéis acceder a una demo online (no requiere registro previo) y a la sección de descargas. La herramienta también es ofrecida en modalidad SaaS.


  • Rapid Miner es otra herramienta open source de BI que dispone de herramientas ETL, análisis de datos, intercambio de datos con otras aplicaciones mediante XML, acceso a fuentes de datos externas (Oracle, SQL Server, MySQL, Postgres,...), potentes gráficos y cuadros de mando,... En su web podéis acceder a una demo online (previo registro), a la sección de descargas así como información de las distintas versiones disponibles como sus características (community, enterprise, big data y OEM).


Además de las herramientas de BI open source anteriores podemos encontrar otras como Tactic, Knime,... Como siempre en este tipo de comparativas no está de más ver lo que dice el cuadrante mágico de Gartner para herramientas de BI al respecto, aparecen las principales herramientas comerciales de BI pero se cuelan dos que disponen de una versión open source, Pentaho y Jaspersoft.

Y hasta aquí el artículo de hoy, ¿utilizáis alguna herramienta open source de BI que no haya mencionado? No dudéis en compartirlo con nuestros lectores a través de los comentarios... Recordad también que dentro de areaTIC podéis encontrar otros artículos interesantes, no dudéis en consultar nuestro archivo, también podéis seguirnos por RSS o las principales redes sociales (twitter, facebook, linkedin...).


miércoles, 7 de agosto de 2013

HTML5 - Jugando con canvas

Hasta ahora no había tenido tiempo de mirarme un poco el elemento

canvas

de

HTML5

y tenía ganas de jugar un poco a ver que permite y que no permite hacer este elemento HTML. Rápidamente al buscar ejemplos en los buscadores me di cuenta que se pueden llegar a conseguir animaciones realmente elaboradas en una página web usando exclusivamente código HTML y js.

La ventaja de todo esto es que no necesitas instalar ningún plugin en el navegador cliente para ver estas animaciones como pasaba con flash o silverlight.

En este enlace podéis ver ejemplos realmente elaborados que no tienen nada que ver con el mío que espero os inspiren.

Por otro lado este es el resultado de 30' jugando con canvas:










Os dejo el código HTML:
<label for="textBox">Texto a Mostrar: </label>
<input id="textBox" type="text" onchange="javascript:fillText();" onkeyup="javascript:fillText();" value="areaTIC"/>
<br /><br />
<label for="txtWidth">Width: </label>
<select id="txtWidth" onchange="javascript:fillText();">
    <option selected>200</option>
    <option>300</option>
</select>
<label for="txtHeight">Height: </label>
<select id="txtHeight" onchange="javascript:fillText();">
    <option selected>100</option>
    <option>200</option>
</select>
<br /><br />
<select id="fontName" onchange="javascript:fillText();">
    <option selected>Arial</option>
    <option>Verdana</option>
</select>
<select id="fontSize" onchange="javascript:fillText();">
    <option selected>30px</option>
    <option>20px</option>
</select>
<br /><br />
<select id="textType" onchange="javascript:fillText();">
    <option selected>Stroke</option>
    <option>Fill</option>
</select>
<br /><br />
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;" />   

<script>
    fillText();
    function fillText() {
        var t = document.getElementById("textBox");
        var c = document.getElementById("myCanvas");
        var fontName = document.getElementById("fontName");
        var fontSize = document.getElementById("fontSize");
        var textType = document.getElementById("textType");
        var heigth = document.getElementById("txtHeight");
        var width = document.getElementById("txtWidth");
        var fontSizeName = fontSize.value + ' ' + fontName.value;
        var x = (width.value / 2);
        var y = (heigth.value / 2);

        c.width = width.value;
        c.height = heigth.value;

        var ctx = c.getContext("2d");
        ctx.clearRect(0, 0, 200, 100);
        ctx.font = fontSizeName;
        ctx.textAlign = "center";

        if (textType.value == "Stroke")
            ctx.strokeText(t.value, x, y);
        else
            ctx.fillText(t.value, x, y);
    }
</script>
Hasta aquí el artículo, recordar que podéis seguir

areaTIC

en las principales redes sociales y os animo a participar con vuestros comentarios y tal. Que vaya bien la semana!