domingo, 1 de septiembre de 2013

:: Resaltar sintaxis en Sublime Text para archivos jade ::

1.- Buscar tu carpeta Packages.



2.- Crea una carpeta dentro de Packages, llamada jade.

3.- Descargar el archivo https://raw.github.com/miksago/jade-tmbundle/master/Syntaxes/Jade.tmLanguage y guardarlo dentro de la carpeta jade.

Listo.


Ejemplo:


domingo, 28 de julio de 2013

Como injectar el ID de sesión en los web services "Batch" de Informática PowerCenter.

Hace poco inicie un proyecto de uso interno en la empresa, el cual consiste en abrir otra puerta a nuestro "Web Services Provider" (el cual es parte de Informática PowerCenter), para poder ejecutar Workflows desde un front. Esto para algunos usuarios que no necesitan aprender a ejecutarlos desde el "Workflow Designer", ó incluso a mi, para probar el workflow en ambientes con más controles como QA y producción.

La mayor parte son proceso "batch" y no pueden tener un criterio de ejecución programada. Generalmente son usados para hacer algunas cargas masivas de información.
Para desarrollar el proyecto, se esta haciendo uso de los web services que están publicados en el Web services HUB, dentro de la carpeta Batch WebService, con ellos se pueden ejecutar y detener workflow, también se puede obtener información de la ejecución e incluso el log. Abajo se muestra una imagen de ello.


Para poder ejecutar varias de las operaciones disponibles por los web services, es necesario iniciar una sesión y posteriormente debe incluirse el valor de dicha sesión en cada "request".

Cito un párrafo del manual "PowerCenter 9.1.0 Web Services Provider Guide", el cual se encuentra en la página 8 del capitulo 2, donde se habla un poco sobre el autenticado. En la parte de abajo, puedes descargar el PDF completo.
"Authentication. For batch web services, the web service client application must call the Login operation before it calls other operations. The Web Services Hub authenticates the request based on the session ID.
For protected real-time web services, the Web Services Hub authenticates the web service client based on the user name token. The web service client must include the user name token in every SOAP request sent to the Web Services Hub. The user name token can include a plain text, hashed, or digested password.
The Web Services Hub does not authenticate web service requests for a public real-time web service."
El valor del "session ID" debe incluirse en el "SOAP Header" de las peticiones.

A continuación se muestra un ejemplo de como agregar el valor de nuestra sesión a todas las peticiones, a través de un "SOAP Handler" ;-], sería conveniente que leyeras mi publicación anterior, ya que ahí se explica como agregar este "SOAP Handler", como están declarados los beans y como son inyectados por medio de Spring.

1.- Como inyectar el ID de sesión dentro del "header" de nuestras peticiones SOAP:


Lo que hace esta clase, es interceptar las peticiones y respuesta SOAP, por lo tanto se comprueba si se trata de una petición, de ser cierto, agregamos el elemento header siempre y cuando, no exista dentro del XML de la petición, después se agrega un elemento llamado "Context", el cual contendrá otro llamado "SessionId", quien finalmente tendrá asignado el valor de la sesión. Más detalles pueden ser consultados en la página 49 del mismo manual, dentro del tópico "Java Client Application for Batch Web Services".

El XML final se verá algo parecido a esto:
Espero subir pronto un proyecto de ejemplo completo a github ;-]


jueves, 18 de julio de 2013

Agregando un interceptor de mensajes SOAP XML (SOAP JaxWs Handler) con Spring de lado del cliente.

La idea con este artículo es mostrar como agregar un "handler" a nuestras peticiones SOAP, las cuales están siendo invocadas con JaxWs.

Con el "handler" se podrá interceptar el mensaje, ya sea cuando se envia la petición (se intercepta antes de enviar) ó cuando se recibe la respuesta  (se intercepta después de recibirla), esto puede servir para modificar la información de la cabecera del mensaje SOAP, con el fin de mandar información especial al servidor, ó simplemente para imprimir el mensaje "crudo" del XML con fines de monitoreo. El objetivo por el momento será solamente imprimir el XML del mensaje.

En Spring existe una forma de inyectar un objeto al bean que implementa la clase proxy generada por la herramienta wsdl2java, este objeto relacionará al "handler" con el webservices a través de la interface  HandlerResolver, esta interface es la que "encadena" a la verdadera clase que interceptará los mensajes. Esta debe implementar a SOAPHandler.

1. Creamos la clase DelegateSOAPHandler que implementará a la clase SOAPHandler.
public boolean handleMessage(SOAPMessageContext context);

El método handleMessage es invocado cuando una petición ó respuesta SOAP es procesada. El método getMessage() devuelve un objeto de tipo SOAPMessage, con el cual podemos acceder al contenido del mensaje SOAP y por lo tanto a modificarlo o sencillamente leerlo. Al final se debe regresar true, de lo contrario si se tienen enlazados más de un "handler", el resto ya no serán procesados.

El método public void handleMessageToLog(SOAPMessageContext context); se ha creado para generar la impresión de nuestro XML dentro del archivo log. Se agrego un poco más de código para darle un formato más claro al mensaje XML.

public boolean handleFault(SOAPMessageContext context);

El método handleFault, procesa los errores que sucedan en la comunicación SOAP. De la misma manera, al final regresamos true.

2. Creamos la clase DefaultHandlerResolver que implementará a la clase HandlerResolver.
Todos los objetos Handler que sean regresado en la lista por medio del método public List getHandlerChain(), seran asociados y usados por nuestro objeto proxy (port object) de nuestro servicio web. En otras palabras, si deseas asociar varias clases del tipo DelegateSOAPHandler. Para poder inyectar nuestra dependencia, se ha creado un método "setter".

3.- Configuracion de beans: applicationContext.xml
Para asignar el bean HandlerResolver, dentro del bean MetaDataWSInformation se debe agregar la propiedad handlerResolver-ref, por medio de esta propiedad, inyectamos el bean handlerResolver el cual es del tipo DefaultHandlerResolver. A su vez al bean handlerResolver por medio de la propiedad handlerList-ref se le inyecta el bean listHandler, quien implementa a SOAPHandler, justamente el objeto quien interceptara las peticiones de la comunicación SOAP.

Con esto ya podemos invocar nuestro objeto proxy que nos provee el bean MetaDataWSInformation para hacer una prueba de que todo funcione correctamente.

Abajo se muestra un ejemplo del XML de una petición y otro de la respuesta.

Por cierto, preferí dejar algunas palabras en inglés, ya que se indexa mejor la publicación, y por otra parte, al traducirlas pierden un poco el sentido :-].

Referencias:
  • http://docs.oracle.com/cd/E15051_01/wls/docs103/webserv_adv/handlers.html
  • http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Fcwbs_jaxwsclients.html
  • http://www.jroller.com/gmazza/entry/jaxws_handler_tutorial