martes, 3 de marzo de 2015

WSO2 ESB: creando una API REST tonta en 1 minuto.

image

Este es un escenario que se nos puede dar en cualquier desarrollo, bien sea en una PoC o como parte de un desarrollo ágil donde necesitamos consumir un servicio REST y no tenemos tiempo para implementar algo desde 0.

Digamos que requimos un servicio que se consulte a través de la siguiente URL:
http://localhost:8281/DummyRESTService/orders

Y queremos que nos devuelva:
{"Order":{"additions":"Milk","drinkName":"Vanilla Flavored Coffee","locked":false,"orderId":123}}


Esta sería su implementación:


<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse"
     name="DummyRESTService"
     context="/DummyRESTService">
   <resource methods="GET" url-mapping="/orders" faultSequence="fault">
      <inSequence>
         <payloadFactory media-type="json">
            <format>{"Order":{"additions":"Milk","drinkName":"Vanilla Flavored Coffee","locked":false,"orderId":123}}</format>
            <args/>
         </payloadFactory>
         <log>
            <property name="JSON-Payload" expression="json-eval($.)"/>
         </log>
         <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
         <property name="messageType"
                   value="application/json"
                   scope="axis2"
                   type="STRING"/>
         <respond/>
      </inSequence>
   </resource>
</api>


Se usa el mediador payloadfactory en su configuración para JSON y dentro de los tags de format se especifica el  JSON que se requiere sea devuelto por el servicio.


Como ven solo hay que cambiar el payload y claro ajustar el nombre, contexto y la url de mapeo.


Importante notar la propiedad NO_ENTITY_BODY la cual permite no enviar el cuerpo de la respuesta, solo los encabezados. Así que se toma como action = remove.


Si se quiere probar se puede usar el firefox con su plugin RESTClient:


image


O usando curl:


image Y listo. Eso es todo.


Tomada la solución de:


http://ruchirawageesha.blogspot.com/2012/07/wso2-esb-sending-dummy-response.html
http://stackoverflow.com/questions/28572800/how-to-implement-a-dummy-rest-api-in-wso2-esb

11 comentarios:

  1. Buen post es cierto que es simple pero para un entorno de prueba no tenemos que volvernos locos implementando nada del otro mundo aqui prondríamos las cosas estáticas como un mock de datos y resolvemos el tema de las pruebas +10

    ResponderEliminar
  2. Hola, creo la api tal y como expones, ejecuto el servicio, y me sale el siguiente error:


    "Both the TO and MessageContext.TRANSPORT_OUT property are null, so nowhere to send"

    ¿qué me puede estar fallando?

    Muchas gracias por las aportaciones,

    ResponderEliminar
  3. Que versión del WSO2 ESB estás usando? Ah y comparte el XML del API para probarla. al parecer no tiene a donde enviar el mensaje de respuesta. Seguro que incluiste el mediador "respond"?

    ResponderEliminar
  4. Hola!!!

    Versión de WSO2 ESB: wso2esb-4.8.1

    XML del API:




    {"Order":{"additions":"Milk","drinkName":"Vanilla Flavored Coffee","locked":false,"orderId":123}}












    Muchas gracias!!

    ResponderEliminar
    Respuestas
    1. No se porque no se ha copiado el API:

      Pero es la misma que has puesto tu en el ejemplo.

      Saludos!

      Eliminar
  5. umm por aqui no deja pasar xml, verdad. mandamelo por la pagina de formulario de contacto. Saludos.

    ResponderEliminar
  6. Hola, como estás invocando al API? Acabo de probar lo que me mandaste con el RESTClient de Firefox y me funciona sin problema con WSO2 ESB 4.8.1

    Mira mi log:

    [2017-05-29 10:28:21,031] INFO - LogMediator To: /DummyRESTService/orders, MessageID: urn:uuid:2c986556-5e78-4182-af6f-4fa126b20e9e, Direction: request, JSON-Payload = {"Order":{"additions":"Milk","drinkName":"Vanilla Flavored Coffee","locked":false,"orderId":123}}

    ResponderEliminar
  7. Hola,

    Pues la estoy invocando, tanto desde RestClient de Firefox, como desde curl (curl http://localhost:XXXX/DummyRESTService/status))

    Y la traza:
    INFO {SERVICE_LOGGER.__SynapseService} - To: /DummyRESTService/orders/, MessageID: urn:uuid:8d7d9bff-c68f-4b95-9f52-32fc2b6f826d, Direction: request, JSON-Payload = {"Order":{"additions":"Milk","drinkName":"Vanilla Flavored Coffee","locked":false,"orderId":123}} {SERVICE_LOGGER.__SynapseService}
    TID: [0] [ESB] [2017-05-29 16:40:09,469] ERROR {org.apache.synapse.core.axis2.Axis2Sender} - Accept:*/*,Accept-Encoding:gzip, deflate,Accept-Language:null,Connection:keep-alive,Content-Type:application/json,Host:esprelrapp01.amaseguros.local:9445,User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0,MilkVanilla Flavored Coffeefalse123 Unexpected error sending message back {org.apache.synapse.core.axis2.Axis2Sender}
    org.apache.axis2.AxisFault: Both the TO and MessageContext.TRANSPORT_OUT property are null, so nowhere to send
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:291)
    at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
    at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:163)
    at org.apache.synapse.mediators.builtin.RespondMediator.mediate(RespondMediator.java:23)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:77)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:47)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:131)
    at org.apache.synapse.rest.Resource.process(Resource.java:297)
    at org.apache.synapse.rest.API.process(API.java:341)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:76)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:63)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:220)
    at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:83)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:344)
    at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:168)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)



    Muchas gracias!!

    ResponderEliminar
  8. El error está claro. No encuentra a donde mandar la respuesta. El tema es que ese error no debe darte, pues la misma configuración define que se manda para el cliente. Ese ESB es nuevo o ya tiene cambios en el axis2.xml?

    Antes del respond, puedes agregarle un log para que te imprima el valor de la propiedad 'To' a ver que tiene.

    ResponderEliminar
  9. Hola,

    Esto es lo que sale:


    TID: [0] [ESB] [2017-05-29 17:34:45,543] INFO {SERVICE_LOGGER.__SynapseService} - To: /DummyRESTService/orders, MessageID: urn:uuid:ee660ae5-eedb-4d64-be6c-fe56e2fa4e79, Direction: request, JSON-Payload = {"Order":{"additions":"Milk","drinkName":"Vanilla Flavored Coffee","locked":false,"orderId":123}} {SERVICE_LOGGER.__SynapseService}
    TID: [0] [ESB] [2017-05-29 17:34:45,543] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: /DummyRESTService/orders, MessageID: urn:uuid:ee660ae5-eedb-4d64-be6c-fe56e2fa4e79, Direction: request, TO = /DummyRESTService/orders {org.apache.synapse.mediators.builtin.LogMediator}
    TID: [0] [ESB] [2017-05-29 17:34:45,543] INFO {SERVICE_LOGGER.__SynapseService} - To: /DummyRESTService/orders, MessageID: urn:uuid:ee660ae5-eedb-4d64-be6c-fe56e2fa4e79, Direction: request, TO = /DummyRESTService/orders {SERVICE_LOGGER.__SynapseService}

    ResponderEliminar
  10. Hola.
    Te recomendaría probar con una instalación fresca de WSO2 ESB 4.8.1 para ver si el error persiste. No debe hacerlo pues acá me funciona OK. Entonces ya sería algo de configuración de tu servidor a mi entender.

    ResponderEliminar