miércoles, 3 de septiembre de 2014

WSO2 con un IDE en la Nube.


WSO2 no deja de sorprendernos y como parte de su solución en la nube "WSO2 Cloud" tenemos la  funcionalidad de poder editar nuestro código y subir los cambios desde un repo temporal de git en la nube hacia el repo remoto. Nos provee de un autocompletamiento de código que si no está al nivel de los IDEs a los que estamos acostumbrados, si para realizar un trabajo rápido o un cambio menor cumple con las espectativas.

Para llegar a esta pantalla del IDE nos vamos a un proyecto en la solución Cloud y seleccionamos del menú de la derecha la opción "Repos & Builds".

De ahí vamos al final y damos clic en el botón "Edit Code", y ya con esto tendremos acceso al IDE y poder realizar los cambios que queramos.

Espero les sea de utilidad y les agilice el desarrollo, es una buena opción para aquellos que se dan cuenta de un cambio a última hora y no tienen a mano su PC o Laptop con su IDE de preferencia. :-D

martes, 2 de septiembre de 2014

WSO2 ESB y el manejo de los logs para la detección de errores

En esta entrada quisieramos mostrarles algo que es básico en cualquier suite para desarrollar soluciones de integración y es la forma en que capturamos los logs generados por los eventos que ocurren con los servicios desplegados.

En el WSO2 ESB existen 3 formas de capturar los logs de los servicios proxy:

  1. Usando el mediador log, dentro de la misma configuración del servicio proxy, algo muy útil durante el desarrollo y para los temas de troubleshooting.
  2. Generando los logs propios del servicio proxy en un fichero a parte del de los logs del propio ESB. A veces dada la cantidad de logs generados se hace un poco complicado seguirle la traza a lo que ocurre con determinado servicio. Esto es muy útil en los ambientes de producción.
  3. Extendiendo las funcionalidades del Synapse, framework base del WSO2 ESB, para incluir lo que se conoce como Observadores. Los cuales se programan para capturar la información que querramos y son adjuntados al servicio proxy en cuestión, especificando incluso el fichero de salida hacia donde se escribirán los logs.

Veamos ahora como podemos usar cada una de estas formas. Para ello usaremos el servicio JAX-WS desplegado en el WSO2 AS de la entrada anterior  y crearemos un servicio proxy.

El servicio JAX-WS lo pueden ver en la siguiente imagen:



El servicio proxy que creamos para la primera forma de captura de los logs lo pueden ver en la siguiente imagen.



Así los logs capturados se pueden ver en la consola o en el fichero de los logs en el ESB, como se muestra en la siguiente imagen.



La segunda forma de capturar los logs, aunque sería mejor decir que es de separar los logs que nos interesan de los logs propios de la ejecución del ESB, es modificar el fichero log4j.properties y añadir las siguientes líneas:

# Configuracion de appender para capturar los logs generados por el servicio UserCollectionProxy
log4j.category.SERVICE_LOGGER.UserCollectionProxy=INFO, PROXY_APPENDER
log4j.additivity.PROXY_APPENDER=false
log4j.appender.PROXY_APPENDER=org.apache.log4j.DailyRollingFileAppender
log4j.appender.PROXY_APPENDER.File=${carbon.home}/repository/logs/${instance.log}/wso2-esb-UserCollectionProxy${instance.log}.log
log4j.appender.PROXY_APPENDER.Append=true
log4j.appender.PROXY_APPENDER.layout=org.apache.log4j.PatternLayout
log4j.appender.PROXY_APPENDER.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%X{ip}-%X{host}] [%t] %5p %c{1} %m%


De esta manera se creará un fichero de nombre wso2-esb-UserCollectionProxy.log que tendrá los logs generados solo por el servicio proxy indicado.

La tercera variante es una implementación más general de la segunda. En la variante 2 para cada servicio debíamos realizar una modificación en el fichero log4j.properties y esto es conveniente cuando no nos interesa observar los logs de todos los servicios si no de algunos en particular. Pero cuando nos interesa observar los logs de todos los servicios, entonces la 3ra opción es la mejor.

Básicamente consiste en implementar un observer que extiende de la clase AbstractSynapseObserver de synapse y posee un método: private void setLogger(ProxyService proxy) throws IOException

Este método es donde se implementa el comportamiento tal y como se puede observar en la siguiente clase java.



package org.jorgesoftdev;

import org.apache.synapse.config.AbstractSynapseObserver;
import org.apache.synapse.core.axis2.ProxyService;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;

/**
 * Created by Jorge on 30/08/14.
 */
public class CustomSynapseObserverForLogging extends AbstractSynapseObserver  {

    private static final Log log = LogFactory.getLog(CustomSynapseObserverForLogging.class);

    public void proxyServiceAdded(ProxyService proxy) {
        try {
            setLogger(proxy);
        } catch (IOException e) {
            log.error("CustomProxyObserver could not set service level logger for the proxy : " + proxy.getName(), e);
        }
    }

    public void proxyServiceRemoved(ProxyService proxy) {
        try {
            setLogger(proxy);
        } catch (IOException e) {
            log.error("CustomProxyObserver could not set service level logger for the proxy : " + proxy.getName(), e);
        }
    }

    private void setLogger(ProxyService proxy) throws IOException {
        String filename = "repository/logs/" + proxy.getName() + ".log";
        String datePattern = "yyyy-MM-dd";
        String SYSTEM_LOG_PATTERN = "[%d] %5p - %x %m {%c}%n";
        PatternLayout layout = new PatternLayout(SYSTEM_LOG_PATTERN);
        DailyRollingFileAppender appender = null;
        appender = new DailyRollingFileAppender(layout, filename, datePattern);
        Logger proxyLogger = Logger.getLogger("SERVICE_LOGGER." + proxy.getName());
        proxyLogger.setLevel(Level.ALL);
        proxyLogger.setAdditivity(false);
        proxyLogger.addAppender(appender);
    }

}




Para implementar la tercera variante he creado un proyecto maven con esta clase implementada, he generado el jar y lo he copiado en la carpeta [ESB_HOME]\repository\components\lib\

Luego he ido al fichero [ESB_HOME]\repository\conf\synapse.properties y he actualizado la línea:
synapse.observers=org.wso2.carbon.mediation.dependency.mgt.DependencyTracker

con la línea:

synapse.observers=org.jorgesoftdev.CustomSynapseObserverForLogging

Luego de reiniciar el servidor en el directorio [ESB_HOME]\repository\logs\ aparecen los ficheros [nombre_servicio_proxy].log con los logs de los respectivos servicios, cada uno por separado.


Cada variante depende de las necesidades de los desarrolladores,  del ambiente en el que se esté ejecutando el ESB, pero al menos a nuestro equipo para un ambiente de desarrollo una combinación de las variantes 1 y 3 es la mejor opción.

La información utilizada para esta entrada fue obtenida de aquí.

Esperamos les sea de utilidad.

lunes, 1 de septiembre de 2014

Introducción a WSO2 Cloud. Nueva propuesta de WSO2.

Hola a todos.

En junio, durante el evento WSO2 Con - Europe 2014 en Barcelona se lanzó la versión beta del servicio WSO2 Cloud de la empresa WSO2. Esta fue la nueva iniciativa luego de la entrega por parte de la empresa a Apache de la solución para la nube StratosLive.

Este nuevo servicio es sumamento fácil de usar. Si ya tienes una cuenta en wso2.com puedes usarla para acceder al mismo, en caso contrario y a través de esta pantalla puedes registrarte y acceder.


La primera prueba que hice fue pasar la implementación de un servicio web desarrollado en jax-ws para esta nueva plataforma y básicamente luego de autenticarse aparece la siguiente pantalla.


Ahí se selecciona App Cloud pues nuestro servicio web estará dentro de un war, ya cuando entramos a la UI debemos crear una aplicación web y esto automáticamente nos provee de un repositorio git y un espacio en jenkin para el despliegue de la aplicación.

Usando el proyecto Example3_JAX-WS expuesto en esta entrada hice los cambios necesarios en el mismo para moverlo al nuevo repo git, cuidando de no modificar los parámetros del pom.xml pues aunque les compile abajo, cuando se trate de subir al repo online les dará problemas.



En nuestro caso usamos SourceTree como cliente GIT para clonar el repo, implementamos los cambios en el servicio y automaticamente cuando se hace un commit al repo online se lanza la tarea en jenkin de compilar y desplegar la aplicación.

Ya con la aplicación desplegada y corriendo usamos el SOAPUI para crear un proyecto y probar el consumo del servicio web desarrollado con JAX-WS.

Para cerrar, revisando los blogs de los desarrolladores de WSO2 me encontré con esta entrada donde se hace un resumen de las principales funcionalidades de este servicio:

WSO2 App Cloud

  • Create applications from scratch - JSP, Jaggery, JAX-WS, JAX-RS
  • Upload existing web applications - JSP, Jaggery
  • Database provisioning for your apps
  • Life cycle management for your app - Dev, Test and Prod environments
  • Team work - A team can collaboratively work on the app
  • Issue tracking tool
  • A Git repository per each application and a build tool.
  • Cloud IDE - For your app development work
  •  And more...

WSO2 API Cloud

  • Create APIs and publish to API store (a store per tenant)
  • Subscribe to APIs in the API store
  • Tier management
  • Throttling
  • Statistics
  • Documentations for APIs

lunes, 25 de agosto de 2014

Componente Carbon UI para gestionar la clusterización (II)

Pues bien como les comenté en la entrada anterior, aquí les dejaré unas capturas de pantalla del componente y una breve descripción de las secciones en las que fui dividiendo el mismo para lograr una mayor usabilidad en el momento de interactuar con el plugin.

Esta es una vista general del plugin:


Para mejorar la usabilidad como les comenté anteriormente fui dividiendo la interfaz por regiones que se corresponden con las regiones del anterior blog. A continuación se las iré mostrando.

Para acceder al mismo, se encuentra ubicado en esta región del menú:


Para activar el clúster y definir la clase que vamos a utilizar para su gestión sería en el siguiente captura:

Para configurarle algunos parámetros que son necesarios a tener presentes en la configuración sería en esta sección:


Para la configuración de propiedades necesarias en esta sección:


Y por último para definir si el host va a ser el administrador del grupo y los grupos que van a intervenir en el clúster diseñe la última sección:


Espero que hasta el momento les haya gustado la interfaz propuesta para el plugin Carbon UI.

Componente Carbon UI para gestionar la clusterización (I)


Como plantea el título de la entrada, creo que hoy en día es muy poco probable que vayamos a usar la Suite de WSO2 sin que clustericemos todas o partes de las herramientas que conformaran nuestra Arquitectura de Infraestructura.

Las herramientas de la plataforma WSO2 realizan el proceso de configuración de la clusterización a través de un fichero en formato XML específicamente en el fichero axis2.xml que se encuentra en WSO2_HOME/repository/conf/axis2/axis2.xml, donde están predefinidos los parámetros que activan su funcionabilidad; sin embargo, la suite no ofrece facilidades para la configuración de este fichero de forma gráfica, el que si bien posee una estructura sugerente, sólo puede actualizarse de forma manual. Se requiere conocimientos avanzados en ficheros con formato XML y por supuesto de clustering.
En ese archivo existen una serie de etiquetas XML correspondientes a los servicios web, la seguridad, los puertos que utilizará la herramienta y los protocolos que estarán activados.

En la sección de configuración del clúster en el fichero axi2.xml, consta de cuatro partes fundamentales: 

Nodo Administrador: Es la que se encarga de la funcionalidad de gestión de los nodos que formarán parte del clúster.


Grupo Administrador: Es la parte que se encarga de administrar cada grupo que es gestionado por el clúster.

Miembros: Es la parte encargada de especificar los miembros estáticos o conocidos en clúster, debiendo especificarse el nombre de host y el puerto principal de estos miembros. 

Agente de Clusterización: Esta parte es la responsable de inicializar todas las funciones relacionadas con el clúster y de los nodos miembros que formarán parte del mismo. 

Para encontrar una mayor descripción de las elementos que componen la configuración de la clusterización de la Suite pueden revisar este enlace Clustering.

Como pueden ver son muchos parámetros a tener en cuenta en el momento de poner en funcionamiento varias herramientas clusterizadas, por lo que me di a la tarea de implementar un plugins Carbon UI para facilitar este proceso, quitándole la responsabilidad al usuario de cometer posibles errores de configuración si se editara de manera manual el fichero de configuración.

En la siguiente entrada verán la propueta de diseño gráfico de la solución.


jueves, 22 de mayo de 2014

Exponiendo datos de nuestra BD a través de APIs con WSO2


En esta entrada quiero mostrar cómo usando varios elementos ya tratados en el blog podemos muy fácilmente exponer nuestros datos a través de APIs y realizar operaciones CRUD sobre ellos.

En esta entrada vimos como crear un servicio de acceso a datos muy fácilmente y en tan solo 3 minutos, que incluyera las operaciones CRUD necesarias para manipular la información de una tabla.

Luego en esta otra entrada vimos como podíamos exponer dichas operaciones de una forma RESTful, lo que en este caso la información la obteníamos como un XML y no en formato JSON.

Así que en esta otra entrada entonces se mostró como podíamos indicarle a la herramienta de WSO2 AS que queríamos también mostrar la información como un JSON.

Hasta aquí tenemos un servicio de acceso a datos desplegado en el WSO2 AS que puede ser consumido por SOAP o por REST y en este último caso las respuestas las puede dar tanto en POX como en JSON, pero eso no es todo.

WSO2 está apostando fuerte por el tema de las APIs, y con su herramienta WSO2 API Manager se ha posicionado entre las mejores empresas en brindar soluciones de este tipo.

Guiándonos por esta otra entrada podemos ir directamente al paso 2 y registrar nuestro servicio en el WSO2 API Publisher para luego gestionarlo en el WSO2 API Store y generar las claves de acceso que nos permitirán probarlo, tal y como se explica en el paso 3.

Ya aquí podemos usar curl o un cliente RESTful para consumir la API siempre usando el token de autorización generado por el API Store.

Por último si deseamos monitorizar el consumo del API solo basta configurar el BAM para que se establezca una conexión entre el AM y el BAM tal y como se muestra aquí.

lunes, 5 de mayo de 2014

Ejemplos de uso de JAX-WS con CXF.

En esta entrada quiero dejarles el código de 3 proyectos que he usado como material de entrenamiento básico en un curso que impartí para el desarrollo de servicios usando CXF, como implementación para el API de JAX-WS.

Proyecto Example3_JAX-RS: Se implementa un servicio RESTful usando la implementación CXF para JAX-WS.

Proyecto Example3_JAX-WS: Se implementa la misma funcionalidad del ejemplo anterior pero se expone como un servicio web a partir de un WSDL ya diseñado, o sea usando el enfoque top-down.

Proyecto Example4_JAX-WS: Se implementa la misma funcionalidad de los ejemplos anteriores pero el servicio está asegurado con el escenario UserNameToken y HTTPS.

En estos ejemplos se usa Spring como mecanismo para mantener todo unido y Maven para la gestión de dependencias.

En el caso del último ejemplo uso las facilidades multimódulo de Maven para separar en módulos los diferentes aspectos que me interesan(servicio, webapp y cliente) En los casos en que se quiera exponer una lógica de negocio ya existente pues se puede crear un módulo para esta lógica de negocio, lo cual siempre facilita su reutilización.

Espero les sea de utilidad.

viernes, 2 de mayo de 2014

WSO2con 2014 en Europa


Con mucha alegría he visto la noticia de que se desarrollará un evento de WSO2con en un país hispano parlante, en este caso España. Así que durante el mes de junio tendremos WSO2 en español :-D

Aquellos que puedan asistir no lo duden ni un minuto. He estado revisando la agenda recien públicada y se debatirán temas muy interesantes.

miércoles, 30 de abril de 2014

WSO2 y su propuesta para el gobierno electrónico

Los temas de gobierno electrónico están muy de moda hoy vinculados a los siguientes tópicos:
  1. SOA.
  2. BPM.
  3. Cloud Computing.
  4. Big Data.
Esta relación se hace bastante “interesante” cuando desde el punto tecnológico las arquitecturas propuestas se pueden instanciar usando una suite como la de WSO2, que abarca cada uno de los puntos anteriores a través de un conjunto de herramientas libres bajo licencia Apache 2.0.

Fig.1. Ejemplo de la relación entre el gobierno electrónico y la computación en la nube


Desde WSO2 nos presentaron un artículo titulado: “Connected Government Cloud Enabling Public Services. The Importance of Functional and Nonfunctional Requirements in Building a Multi-tenanted Digital Government Stack” en el cual nos llevan a un enfoque basado en 3 modelos diferentes que combinan la Computación en la Nube con el Gobierno electrónico.

Estos modelos son:

  • Controlado y gobernado centralmente: Los sistemas son controlados centralmente lo que implica que se provee un modelo SaaS a los gobiernos locales y además las políticas son aplicadas a nivel nacional y aplicadas a nivel local.
  • Controlado centralmente pero gobernado localmente: en este caso aplica lo mismo del modelo anterior donde el gobierno central brinda un modelo SaaS a los gobiernos locales, pero este último puede desplegar y aplicar sus políticas encima del SaaS.
  • Controlado y gobernado localmente: en este caso el gobierno central no juega un papel importante ya que los sistemas son desplegados a nivel local y el hosting y la infraestructura es gobernada por el propio gobierno local.

Para más información sobre las ventajas y desventajas de cada modelo así como el macheo entre un tipo de gobierno el tipo de modelo a aplicar pueden consultar el artículo en cuestión.

El artículo nos propone como se podría ver una solución de arquitectura para el gobierno electrónico usando los componentes de su suite.


lunes, 7 de abril de 2014

MULE vs WSO2 en el patrón de integración Scatter-Gather.

Hace unos días revisando el blog de MULE me topé con esta entrada del 3/04/2014 donde se explica como con la nueva versión 3.5 se ha añadido una funcionalidad para eliminar algunos problemas de las versiones anteriores a la hora de implementar el patrón de integración "Scatter-Gather".

Este patrón define la forma de enviar un mismo mensaje a diferentes destinos con un objetivo determinado y luego procesar la respuesta de una manera específica, tal como pueden ver en la imagen siguiente.




Un objetivo que nos llevaría a implementar este patrón puede ser el mandar un mismo request a diferentes sistemas que se encargan de procesar reservaciones de vuelos y a partir de la respuesta recibida de cada uno seleccionar la mejor para la solución final, tanto los ejemplos de MULE como de WSO2 seleccionan de las respuestas recibidas la más barata. Es solo un ejemplo pero les puede dar idea de la utilidad del patrón.

MULE antes de la versión 3.5 implementaba este patrón usando un router multicasting <all>, el cual presentaba las siguientes limitantes según se comenta en el propio artículo:
  1. Procesamiento en secuencia, o sea uno detrás del otro.
  2. Problemas en el manejo de los errores.
  3. Poca personalización de la solución para adecuarla a las necesidades específicas de los desarrolladores.
En la entrada que les comentaba con la introducción del router <scatter-gather> le han dado solución a estos problemas.

Lo interesante es que MULE hace esto ahora, pero WSO2 lo tiene hecho desde hace un tiempo ya y no con un mediador si no con la combinación de varios mediadores, lo que implica que la solución aunque parezca un poco más complicada técnicamente permite una mayor personalización para los desarrolladores. Y creo que esto es genial, el tener pequeños bloques de construcción que puedan ser usados para casi cualquier cosa y pienso que esa es la idea de WSO2. Si a esto le sumamos que podemos crear templates a partir de una solución en particular y luego usar dicho template para recrear una nueva implementación del patrón, pues nos ahorramos mucha configuración.
Solo les dejo el XML del servicio proxy para que lo vean:


<proxy xmlns="http://ws.apache.org/ns/synapse" name="ScatterGatherProxy" transports="https http" startOnLoad="true" trace="disable">  
    <description/>  
    <target>  
        <inSequence>  
            <clone>  
                <target>  
                    <endpoint name="vendorA">  
                        <address uri="http://localhost:9000/services/SimpleStockQuoteService/"/>  
                    </endpoint>  
                </target>  
                <target>  
                    <endpoint name="vendorB">  
                        <address uri="http://localhost:9001/services/SimpleStockQuoteService/"/>  
                    </endpoint>  
                </target>  
                <target>  
                    <endpoint name="vendorC">  
                        <address uri="http://localhost:9002/services/SimpleStockQuoteService/"/>  
                    </endpoint>  
                </target>  
            </clone>  
        </inSequence>  
        <outSequence>  
            <log level="full"/>  
            <aggregate>  
                <completeCondition>  
                    <messageCount min="3"/>  
                </completeCondition>  
                <onComplete xmlns:m1="http://services.samples/xsd" xmlns:m0="http://services.samples" expression="//m0:return">  
                    <enrich>  
                        <source xmlns:m1="http://services.samples/xsd" clone="true" xpath="//m0:return[not(preceding-sibling::m0:return/m1:last <= m1:last) and not(following-sibling::m0:return/m1:last < m1:last)]"/>  
                        <target type="body"/>  
                    </enrich>  
                    <send/>  
                </onComplete>  
            </aggregate>  
        </outSequence>  
    </target>  
</proxy>


La solución que propone WSO2 para este patrón la pueden encontrar en este enlace muy bien documentada y lista para ser probada con un paso a paso, así que no la recrearé en esta entrada.