sábado, 8 de diciembre de 2012

Generar un cliente con Axis2



Generar un cliente

  • Descargamos los binarios del axis2, y los registramos como variables de entorno
    AXIS2_HOME : c:\axis2\
  • En el path ";%AXIS2_HOME%\bin"
  • Luego creamos un directorio donde se generaran las clases java, que seran utilizadas
    para realizar el consumo del servicio web, ejecutamos el siguiente comando
    c:\axis2\carpeta\wsdl2java -p com.servicio.ws.sample1.cliente -d adb -S . -or -uri http://127.0.0.1:8080/axis2/services/Calculadora?wsdl
  • El parámetro p indica el nombre del paquete donde deseamos que se generen las clases.
  • El parámetro d indica el tipo de Databinding, es decir, el mapeo entre XML y objetos Java que deseamos.
    Usamos el tipo ADB (Axis Data Binding) que usa AXIOM (Axis Object Model) un modelo especialmente creado
    para Axis que proporciona un alto rendimiento debido a que está basado en el API de StAX (Streaming API for XML) (Alternativas a DOM y SAX)
    una forma de parsear XML bajo demanda, es decir, sólo se parsea lo que se necesita en cada momento.
  • El parámetro S indica el nombre de la carpeta en donde deseamos que se generen las clases (por defecto crea una carpeta src)
  • El parámetro uri indica el WSDL de partida.

Invocar el servicio Web

  1. package com.autentia.ws.sample1.test;   
  2.   
  3. import com.autentia.ws.sample1.cliente.*;   




  • import com.autentia.ws.sample1.cliente.CalculadoraStub.Sumar;   
  • import com.autentia.ws.sample1.cliente.CalculadoraStub.SumarResponse;   
  •   
  • /**  
  •  * Ejemplo de invocación SINCRONA del servicio Web  
  •  *   
  •  * @see Creador de http://www.mobiletest.es       
  •  */  
  • public class Appication1 {   
  •     /**  
  •      * Ejemplo de invocación del servicio  
  •      */  
  •     public static void main(String[] args) throws Exception {   
  •         CalculadoraStub stub = new CalculadoraStub();   
  •         Sumar operacion = new Sumar();   
  •         SumarResponse response = null;   
  •   
  •         // Establecemos los parámetros de la operación   
  •         operacion.setParam0(100);   
  •         operacion.setParam1(200);   
  •   
  •         // Invocamos el WS   
  •         response = stub.sumar(operacion);   
  •   
  •         // Mostramos el resultado   
  •         System.out.println(response.get_return());   
  •     }   
  • }   
  •       

  • Conclusiones

    Bueno, como pueden ver la generación de servicios Web con Axis2 así como su despliegue o generación de clientes no tiene mucha dificultad. Axis2 soporta los patrones de mensajería (Síncrona/Asíncrona, Comunicación 1 a 1, 1 a N, N a M, mensajería por eventos, etc.) definidos WSDL 2, así como varios tipos de DataBinding que se salen del alcance de este tutorial.

    Saludos
    Renzo Huertas


    Creación de un servicio Web con Axis2

    Creación de un servicio Web

    1. Definición de una interface Java a partir de la cual generaremos el servicio Web.
    2. Generar la definición del servicio Web (WSDL) a partir del interface.
    3. Generar el esqueleto (Skeleton) del servicio Web del WSDL.
    4. Implementar la lógica de negocio del servicio Web.
    5. Generar el archivo del Servicio Web AAR (Axis Archive)
    6. Desplegar el servicio Web.

    Definición de una interface Java a partir de la cual generaremos el servicio Web

    1. package com.autentia.ws.sample1;   
    2.   
    3. /**  
    4.  * Interfaz Calculadora   
    5.  *   
    6.  * @see http://www.mobiletest.es  
    7.  */  
    8. public interface Calculadora {   



  •     public int sumar(int op1, int op2);   
  • }         
  •       

  • Generar la definición del servicio Web (WSDL) a partir del interface.

    %AXIS_HOME%/bin/java2wsdl -of calculadora.wsdl -cn com.servicio.ws.sample1.Calculadora
    • En donde el parámetro of es el nombre del archivo WSDL que deseamos generar
    • En donde el parámetro cn es el nombre de la clase a partir de la cual deseamos generar el WSDL.

    Archivo generado: calculadora.xsdl


    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"    




  •      xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns0="http://sample1.ws.autentia.com"  
  •      xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"    
  •      xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"    
  •      xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"    
  •      targetNamespace="http://sample1.ws.autentia.com">  
  •     <wsdl:types>  
  •         <xs:schema xmlns:ns="http://sample1.ws.autentia.com" attributeFormDefault="qualified"    
  •         elementFormDefault="qualified" targetNamespace="http://sample1.ws.autentia.com">  
  •             <xs:element name="sumar">  
  •                 <xs:complexType>  
  •                     <xs:sequence>  
  •                         <xs:element minOccurs="0" name="param0" type="xs:int"/>  
  •                         <xs:element minOccurs="0" name="param1" type="xs:int"/>  
  •                     </xs:sequence>  
  •                 </xs:complexType>  
  •             </xs:element>  
  •             <xs:element name="sumarResponse">  
  •                 <xs:complexType>  
  •                     <xs:sequence>  
  •                         <xs:element minOccurs="0" name="return" type="xs:int"/>  
  •                     </xs:sequence>  
  •                 </xs:complexType>  
  •             </xs:element>  
  •         </xs:schema>  
  •     </wsdl:types>  
  •     <wsdl:message name="sumarRequest">  
  •         <wsdl:part name="parameters" element="ns0:sumar"/>  
  •     </wsdl:message>  
  •     <wsdl:message name="sumarResponse">  
  •         <wsdl:part name="parameters" element="ns0:sumarResponse"/>  
  •     </wsdl:message>  
  •     <wsdl:portType name="CalculadoraPortType">  
  •         <wsdl:operation name="sumar">  
  •             <wsdl:input message="ns0:sumarRequest" wsaw:Action="urn:sumar"/>  
  •             <wsdl:output message="ns0:sumarResponse" wsaw:Action="urn:sumarResponse"/>  
  •         </wsdl:operation>  
  •     </wsdl:portType>  
  •     <wsdl:binding name="CalculadoraSOAP11Binding" type="ns0:CalculadoraPortType">  
  •         <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>  
  •         <wsdl:operation name="sumar">  
  •             <soap:operation soapAction="urn:sumar" style="document"/>  
  •             <wsdl:input>  
  •                 <soap:body use="literal"/>  
  •             </wsdl:input>  
  •             <wsdl:output>  
  •                 <soap:body use="literal"/>  
  •             </wsdl:output>  
  •         </wsdl:operation>  
  •     </wsdl:binding>  
  •     <wsdl:binding name="CalculadoraSOAP12Binding" type="ns0:CalculadoraPortType">  
  •         <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>  
  •         <wsdl:operation name="sumar">  
  •             <soap12:operation soapAction="urn:sumar" style="document"/>  
  •             <wsdl:input>  
  •                 <soap12:body use="literal"/>  
  •             </wsdl:input>  
  •             <wsdl:output>  
  •                 <soap12:body use="literal"/>  
  •             </wsdl:output>  
  •         </wsdl:operation>  
  •     </wsdl:binding>  
  •     <wsdl:binding name="CalculadoraHttpBinding" type="ns0:CalculadoraPortType">  
  •         <http:binding verb="POST"/>  
  •         <wsdl:operation name="sumar">  
  •             <http:operation location="Calculadora/sumar"/>  
  •             <wsdl:input>  
  •                 <mime:content type="text/xml" part="sumar"/>  
  •             </wsdl:input>  
  •             <wsdl:output>  
  •                 <mime:content type="text/xml" part="sumar"/>  
  •             </wsdl:output>  
  •         </wsdl:operation>  
  •     </wsdl:binding>  
  •     <wsdl:service name="Calculadora">  
  •         <wsdl:port name="CalculadoraSOAP11port_http" binding="ns0:CalculadoraSOAP11Binding">  
  •             <soap:address location="http://localhost:8080/axis2/services/Calculadora"/>  
  •         </wsdl:port>  
  •         <wsdl:port name="CalculadoraSOAP12port_http" binding="ns0:CalculadoraSOAP12Binding">  
  •             <soap12:address location="http://localhost:8080/axis2/services/Calculadora"/>  
  •         </wsdl:port>  
  •         <wsdl:port name="CalculadoraHttpport" binding="ns0:CalculadoraHttpBinding">  
  •             <http:address location="http://localhost:8080/axis2/services/Calculadora"/>  
  •         </wsdl:port>  
  •     </wsdl:service>  
  • </wsdl:definitions>  
  •   
  •       

  • Generar el esqueleto (Skeleton) del servicio Web a partir del WSDL.

    %AXIS_HOME%/bin/wsdl2java -p com.servicio.ws.sample1.servidor -S . -or -ss -sd -u --noMessageReceiver -uri calculadora.wsdl
    • El parámetro p indica el nombre del paquete donde deseamos que se generen las clases.
    • El parámetro S indica el nombre de la carpeta en donde deseamos que se generen las clases (por defecto crea una carpeta src)
    • El parámetro or indica que se sobreescriban los archivos.
    • El parámetro ss indica que se generen las clases del servicio web (Por defecto NO se generan)
    • El parámetro sd indica que se genere el descriptor de despliegue del servicio web.
    • El parámetro u indica que no se generen innerclases sino que cada clase está en un archico propio.
    • El parámetro noMessageReceiver indica que no se genere un Message Receiver especifico para el servicio Web.
    • El parámetro uri indica el WSDL de partida.
    El descriptor de despliegue generado (services.xml):
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <serviceGroup>  



  •     <service name="Calculadora">  
  •         <parameter name="ServiceClass">com.autentia.ws.sample1.servidor.CalculadoraSkeleton</parameter>  
  •         <operation name="sumar">  
  •             <actionMapping>urn:sumar</actionMapping>  
  •             <outputActionMapping>urn:sumarResponse</outputActionMapping>  
  •             <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>  
  •         </operation>  
  •     </service>  
  • </serviceGroup>  
  •       

  • Implementar la lógica de negocio del servicio Web.

    1. /**   
    2.  * Implementación del Servicio Web   
    3.  */     
    4. package com.autentia.ws.sample1.servidor;     



  •   public class CalculadoraSkeleton {     
  •     public com.autentia.ws.sample1.SumarResponse sumar(com.autentia.ws.sample1.Sumar sumar) {     
  •         com.autentia.ws.sample1.SumarResponse response = new com.autentia.ws.sample1.SumarResponse();     
  •         response.set_return(sumar.getParam0() + sumar.getParam1());     
  •         return response;     
  •     }     
  • }     
  •       

  • Generar el archivo del Servicio Web AAR (Axis Archive)

    Para desplegar un servicios Web en Axis2, debemos generar un archivo AAR.
    Los archivos AAR, son como los archivos WAR, EAR. Es decir son archivos JAR o ZIP que contienen archivos y directorios bajo una estructura definida.
    Los pasos generar el archivo aar son:
    1. Creamos una carpeta de nombre Calculadora
    2. Dentro de la carpeta Calculadora copiamos las clases com.autentia.ws.sample1 manteniendo la estructura.
    3. Dentro de la carpeta Calculadora creamos una carpeta de nombre META-INF y compiamos dentro el archivo services.xml.
    4. Empaquetamos la carpeta Calculadora en un archivo Calculadora.aar. Para ello estando dentro del directorio Calculadora ejecutamos la siguiente instrucción: %JAVA_HOME%/bin/jar -cvf Calculadora.aar *

    Desplegar el servicio Web.

    Existen varios métodos de despliegue de un Servicio Web en Axis2, los más comunes son:
    1. A través la opción "Upload Service" de la página de administración de Axis2.
    2. Copiar el "AAR" al directorio <AXIS_WEBAPP_HOME>\repository\services. Siendo AXIS_WEBAPP_HOME el directorio donde está desplegado Axis2 en el servidor de aplicaciones o contenedor de Servlet.

    Documentar Servicios REST

    Swagger: Documentar Servicios REST


    swagger es un framework (especificación e implementación) completo para describir, producir, consumir y visualizar Servicios REST.

    El objetivo de Swagger es que la documentación del sistema se actualice conforme se actualice el Servicio, de modo que la documentación de los métodos, parámetros y modelo esté integrada en el código del Servicio permitiendo que las APIs estén siempre sincronizadas.
    · Como Swagger es una especificación es independiente del lenguaje.
    · Swagger ofrece implementaciones en Scala, Java y HTML5
    · Swagger permite generar clientes Scala, Java, Javascript, Ruby, PHP y ActionScrip 3.
    · Swagger soporta JSON y XML.
    · Swagger UI framework permite a desarrolladores y usuarios interactuar con el API
    Swagger se compone de varios módulos, entre ellos:
    · Swagger UI es una aplicación HTML (+JS+CSS) que permiten generar documentación de un API Swagger.
    Es en esencia una consola web completamente HTML que permite:
    · listar operaciones:

    · ejecutar operaciones

    · Swagger Core define las anotaciones Java y la lógica requerida para generar un cliente o servidor Swagger. Incluye ejemplos en Java, Scala, con Play2 framework:
    · Swagger node.js Servidor Swagger stand-alone escrito en Javascript con node.js
    · Swagger Java Sample App Servidor Swagger stand-alone escrito en Java que demuestra como habilitar Swagger en tu API. El ejemplo se lanza directamente con:
    > mvn package -Dlog4j.configuration=file:./conf/log4j.properties jetty:run
    Abrimos Swagger UI local con esta url http://localhost:8002/api/resources.json

    Si revisamos el código de la clase PetResource veo que Swagger ofrece anotaciones para documentar las operaciones (@ApiOperation), los errores (@ApiError) y los parámetros (@ApiParam)

    Que en la consola web quedan:

    Y cuando se produce error:

    · Swagger CodeGen ofrece un motor de plantillas para generar código cliente en diferentes lenguajes parseando la declaración de recursos.
    Por ejemplo en Javascript:
    ./bin/generate-js-lib.sh http://petstore.swagger.wordnik.com/api "" "" "generated-files"

    Saludos
    Renzo Huertas.