Mostrando las entradas con la etiqueta api. Mostrar todas las entradas
Mostrando las entradas con la etiqueta api. Mostrar todas las entradas

miércoles, diciembre 08, 2010

¿Quién dijo que enviar correos era fácil? v2010

Hace algunos ayeres me hice la misma pregunta y hoy me toca hacerla de nuevo. Por fortuna encontré la actualización de la respuesta.

El tiempo pasa...

Finito.

lunes, septiembre 03, 2007

Bitácoras, Trazas, Logs, Logging

Una consabida forma de ver que sucede con tus programas es "pintar" los valores de tus variables. Esta rústica forma de depurar también tiene otra acepción: loggear :S

¿Quién dijo que poner System.out.println (javeros) o Console.WriteLine (.net) por cada línea es manejar una bitácora? No lo sé, pero en los ambientes java (que es lo que tengo más cercano) tenemos mega-archivos log de cientos de megabytes generados con poderosos System.out.println statements. Logging is cool!

Pero, eso no es logging. En casi cada aplicación "grande" o "empresarial" (lo que sea que significa esto) se incluye algún mecanismo de bitácoras. Agregar sentencias de rastreo es un mecanismo de "bajo nivel" para depurar código. Puede ser que sea la única opción por no existir un depurador para la plataforma o por que ya se trata de un ambiente multitarea/multihilos.

En el caso de una aplicación ejecutándose en un ambiente de producción, tampoco se puede hacer uso de herramientas de desarrollo o depuración. Casos así requieren que se le otorgue a los administradores u operadores herramientas que les permitan monitorear el comportamiento de los sistemas.

Para hablar de logging se requiere cumplir una serie de requisitos. Uno de ellos son los "contextos", entidades que contienen la información precisa de la ejecución de la aplicación. También se requiere distinguir diferentes niveles de severidad, desde el error fatal hasta mensajes de depuración; estas características deben poder configurarse fuera del código de la aplicación, es decir, en los programas incluimos todas las llamadas de rastreo que consideremos pero dependiendo de la configuración se van ir grabando las seleccionadas.

También tiene sus desventajas. El registro de entradas en archivos o bases de datos consume tiempo de procesador, llamadas a dispositivos que finalmente se ve como un cierto grado de lentitud en la aplicación. Si se registran demasiadas entradas, el log se torna ilegible. Si se filtran demasiados niveles de severidad, puede ser que se pierdan elementos que podrían auxiliar a resolver problemas.

Como ya es costumbre, el mundo java ha pasado por esto antes y gracias a la colaboración de muchas personas se construyó un framework para este tipo de necesidades. Ha sido tal el éxito de esta iniciativa que se desarrollaron componentes similares para otras plataformas y lenguajes (C++/PHP/Ruby) e incluso se incluye en algunos productos comerciales, BEA WebLogic Server por ejemplo (aunque ninguno de los programadores que conozco lo usan, siguen con sus pinchis println's) y obvio, también se construyo para .NET.

En este caso, log4net respeta todos los principios de su ancestro log4j y tenemos archivos de configuración, contextos, jerarquía de loggers e implementaciones de "appenders" que nos permiten tener diferentes destinos para nuestros logs. Ahora si, "logs".

El primer ejercicio de muestra del uso de log4net lo pueden encontrar en mi repositorio de ideas Google Code. Mediante subversion pueden obtener una copia de trabajo y trastear un rato con él.

Finito.

miércoles, agosto 22, 2007

Uno de muchas

En este post tengo que agregar varias, varias notas.

Para la gente con la que tengo contacto más directo, principalmente por twitter esto ya no es noticia: ahora soy el flamante propietario de una Apple Macbook :P ¡Lo hice!

Ha sido una experiencia bastante rica, un ambiente agradable, un desempeño excelente y un ambiente familiar, después de todo en el fondo se trata de una variante de *nix. El único problema ha sido AirPort. Nomás no puedo configurarlo con los pinchis modems 2wire. Sucks.

Lo primero fue configurar un ambiente de desarrollo para lo cual me apoyé en los MacPorts, sin ahondar en detalles es un tipo de emerge: get code, compile, install. Easy, easy. Aún así me costó trabajo generar un ambiente para compilar Mono, cosa que conseguí hasta hoy.

Otra cosa agradable fue que resolvieron un bug que levanté en Mono, más detalles en mi blog hermano PartnerApi.

En la parte de las malas nuevas, mi ponencia fue rechazada en el EnLi ¡buaaa! ni modos :( (Sí quería ir).

Otra mala noticia es que pasó menos tiempo en línea gracias a los errores de Hellmex. Me suspendieron el servicio de banda ancha y teléfono por el desmadre que traen con el contrato desde que cambiamos de domicilio. Nomás pa'que le midan: el recibo con el nuevo número sigue llegando al domicilio anterior :S

Y pus bueno, sigo en el underground con Operación PyME. Ahora se me ha clavado la loca idea de desarrollar (bueno, seguir desarrollando) un framework que usé hace un par de años derivado de CSLA.NET y además una serie de Helpers muy similares a los famosos ApplicationBlocks; ya estaré posteando más detalles.

Finito.

martes, junio 26, 2007

PartnerApi Library: Por fin ve la luz

Hace algunos años fui contratado para integrar un CRM y Salesforce (se llamaba así en ese entonces). Para realizar la integración usé C# y el Enterprise API de Salesforce para llevar los datos del CRM al repositorio en línea de Salesforce. Un ejercicio harto interesante. También leí algo acerca de la PartnerApi y de ahí surgió la inquietud de utilizarla.

El objetivo que se me presentó en mi mente fue crear una biblioteca que simplificara el uso de esta PartnerApi y pues después de mmuuuucho tiempo aquí está.

Acabo de publicar el código, licenciado bajo LGPL, para que todo mundo lo revise, lo use y ojalá y contribuya a este proyecto.

Cualquier comentario, sugerencia o pregunta son bienvenidas.

Finito.

miércoles, mayo 09, 2007

Entre servicios te veas

En una prueba de integración entre una aplicación .NET y otra desarrollada en Java nos apareció este mensaje:

Exito: 0
Código Error: 100
Desc. Error: mx.gob.imss.sigoi.quejaVerbal.exception.ValidaCampoException:
El campo Calidad de la persona que se comunica es requerido.
El campo Nombre de la persona que se comunica es requerido.
El campo Apellido paterno de la persona que se comunica es requerido.
El campo Lada de teléfono particular de la persona que se comunica tiene que ser numérico.
El campo Lada de teléfono particular de la persona que se comunica tiene una longitud no valida, menor a 2 Caracteres
El campo Teléfono particular de la persona que se comunica tiene que ser numérico.
El campo Teléfono particular de la persona que se comunica tiene una longitud no valida, menor a 8 Caracteres
El campo Teléfono celular de la persona que se comunica tiene que ser numérico.
El campo Teléfono celular de la persona que se comunica tiene una longitud no valida, menor a 12 Caracteres
El campo Correo electrónico de la persona que se comunica no tiene un formato adecuado
Se tiene que incluir al menos un medio de contacto valido de la persona que se
comunica: Lada y número de teléfono particular, número de teléfono celular, correo electrónico, o dirección completa
Es necesario capturar el NSS de la persona que se comunica
Es necesario capturar el NSS de la persona que solicita el servicio
El campo Calidad de la persona que solicita el servicio es requerido.
El campo Teléfono celular del usuario que solicita el servicio tiene que ser numérico.
El campo Teléfono celular del usuario que solicita el servicio tiene una longitud no valida, menor a 12 Caracteres
El campo Entidad federativa del usuario que solicita el servicio tiene que ser numérico.
El campo Entidad federativa del usuario que solicita el servicio no es un valor válido de catálogo
El campo Clasificación de la solicitud del planteamiento tiene que ser numérico.
El campo Clasificación de la solicitud del planteamiento no es un valor válido de catálogo
El campo Tema del planteamiento tiene que ser numérico.
El campo Tema del planteamiento no es un valor válido de catálogo
El campo Subtema del planteamiento tiene que ser numérico.
El campo Subtema del planteamiento no es un valor válido de catálogo
El campo Delegación de Adscripción del planteamiento no es un valor válido de catálogo
El campo Unidad Medica de Adscripción del planteamiento tiene que ser numérico.
El campo Unidad Medica de Adscripción del planteamiento no es un valor válido de catálogo
El campo Delegación o UMAE involucrada en la gestión o queja del planteamiento tiene que ser numérico.
El campo Delegación o UMAE involucrada en la gestión o queja del planteamiento no es un valor válido de catálogo
El campo Subdeleación y/o Unidad involucrada en la gestión o queja del planteamiento tiene que ser numérico.
El campo Subdeleación y/o Unidad involucrada en la gestión o queja del planteamiento no es un valor válido de catálogo

¿Qué tiene de malo? (aparte de algunas faltas de ortografía) Son dos servicios que están intercambiando mensajes entre sí. No tienen interacción con el usuario, así que este tipo de mensajes, descriptivos y detallados, son completamente desaprovechados en este contexto.

Entonces ¿cuál es el modo correcto de devolver errores en este caso? No sé cual sea el modo correcto. Lo que a mi me gusta es el estilo de AppExchange Web Service API.

AppExchange (anteriormente conocida como Salesforce) es una empresa que ofrece software as a service (SaaS), en particular un CRM que compite directamente contra los grandes: Siebel, SAP y otros. Les ha ganado una gran tajada del mercado y sigue abriendo áreas de oportunidad. La API que comento la ofrecen mediante servicios web y tiene la funcionalidad de agregar, actualizar, borrar y buscar items de su mega repositorio de datos.

Así, en esas operaciones obviamente se envían y devuelven resultados en un contexto de integración de servicios. ¿Cómo le hacen? Va la referencia del API:

SaveResult[] = sfdc.create(sObject[] sObjects);


Tenemos la llamada create que recibe un arreglo de sObjects (tipo nativo de AppExchange) y como resultado devuelve un arreglo de objetos SaveResult. Ahora veamos SaveResult:

private Error[] errorsField;
private string idField;
private bool successField;


Nos devuelve un objeto con el identificador único (idField), una bandera de éxito o fracaso (successField) y un arreglo de objetos Error, igualmente veamos:

private string[] fieldsField;
private string messageField;
private StatusCode statusCodeField;


En fieldsField tenemos el o los nombres de los campos que provocaron el error; messageField es el texto descriptivo del error y finalmente statusCodeField que es el código que identifica el error dentro de un catálogo disponible en el WSDL del servicio.

Si bien tenemos un texto descriptivo, tenemos otras referencias (statusCodeField, successField) que nos permiten atender el problema y darle solución dentro de un contexto de integración.

A mi parecer es la falta de comprensión de los escenarios en los que se trabaja lo que provoca este tipo de diseños. Ya se requiere cambiar el modelo y empezar a modelar servicios. En algún momento habrá un servicio que se encargue de interactuar con el usuario y habrá que darle la suficiente información para que resuelva los problemas que lleguen a aparecer.

Por eso, entre servicios te veas, comportate como un servicio.

Finito.