WSO2 API manager - How to send Error/Fault message back to the Client from InSequence - wso2

I have created a REST API using WSO2 API Manager (StockQuoteService) and configured a back end SOAP based web service (converting REST to SOAP) from where it will be getting the data based on the URL template.
In the "In Sequence", I have used a Switch mediator to send the request to different back end endpoints based on incoming data whereas in the default scenario (when no case match), I want to send the error message back to the client that the "Input message is invalid".
I have tried using the Send mediator, Respond Mediator, Sequence Mediator but still no success (may be doing something wrong) as still I am getting "no response from server" error when I try to invoke the URL which doesn't match any case of Switch and goes to Default.
How can I send the Error/Fault message back to the client from In Sequence of WSO2 API Manager?

In my scenario, the input sequence I used the switch mediator and I invoke an operation or another, in the default option I create my failure response
<inSequence>
<switch xmlns:xsd="http://pharmacy.arce.org/xsd"
description=""
source="//xsd:desc">
<case regex="NATURAL">
<log description="Search Pharmacy" level="custom" separator=",">
<property name="STATUS" value="Search Pharmacy"/>
</log>
<payloadFactory media-type="xml">
<format>
<p:searchpharmacy xmlns:p="http://pharmacy.arce.org">
<ax22:pharmacy xmlns:ax22="http://pharmacy.arce.org">
<xs:desc xmlns:xs="http://pharmacy.arce.org/xsd">$1</xs:desc>
<xs:id xmlns:xs="http://pharmacy.arce.org/xsd">$2</xs:id>
<xs:latitude xmlns:xs="http://pharmacy.arce.org/xsd">$3</xs:latitude>
<xs:longitude xmlns:xs="http://pharmacy.arce.org/xsd">$4</xs:longitude>
</ax22:pharmacy>
</p:searchpharmacy>
</format>
<args>
<arg evaluator="xml" expression="//xsd:desc"/>
<arg evaluator="xml" expression="//xsd:id"/>
<arg evaluator="xml" expression="//xsd:latitude"/>
<arg evaluator="xml" expression="//xsd:longitude"/>
</args>
</payloadFactory>
<header name="To" scope="default" value="urn:searchpharmacy"/>
<log level="full" separator=",">
<property name="Mensaje" value="Cuerpo"/>
</log>
</case>
<case regex="EXPERIMENTAL">
<log description="Search Pharmacy Direction" level="custom" separator=",">
<property name="STATUS" value="Search Pharmacy Direction Request"/>
</log>
<payloadFactory media-type="xml">
<format>
<p:searchPhone xmlns:p="http://pharmacy.arce.org">
<ax22:pharmacy xmlns:ax22="http://pharmacy.arce.org">
<xs:desc xmlns:xs="http://pharmacy.arce.org/xsd">$1</xs:desc>
<xs:id xmlns:xs="http://pharmacy.arce.org/xsd">$2</xs:id>
<xs:latitude xmlns:xs="http://pharmacy.arce.org/xsd">$3</xs:latitude>
<xs:longitude xmlns:xs="http://pharmacy.arce.org/xsd">$4</xs:longitude>
</ax22:pharmacy>
</p:searchPhone>
</format>
<args>
<arg evaluator="xml" expression="//xsd:desc"/>
<arg evaluator="xml" expression="//xsd:id"/>
<arg evaluator="xml" expression="//xsd:latitude"/>
<arg evaluator="xml" expression="//xsd:longitude"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:searchPhone"/>
<property name="SOAPAction" scope="transport" type="STRING" value=""/>
<log level="full" separator=",">
<property name="Data" value="Body"/>
</log>
</case>
<default>
<log description="Fault" level="custom" separator=",">
<property name="STATUS" value="Invoke fault "/>
</log>
<payloadFactory media-type="xml">
<format>
<rs:fault xmlns:rs="http://pharmacy.arce.org">
<rs:code>-1</rs:code>
<rs:type>Invocation error</rs:type>
<rs:message>No operation has been invoked</rs:message>
<rs:description>The value of the input parameter is not valid</rs:description>
</rs:fault>
</format>
<args/>
</payloadFactory>
<respond/>
</default>
</switch>
</inSequence>
Here is the default section
<default>
<log description="Fault" level="custom" separator=",">
<property name="STATUS" value="Invoke fault "/>
</log>
<payloadFactory media-type="xml">
<format>
<rs:fault xmlns:rs="http://pharmacy.arce.org">
<rs:code>-1</rs:code>
<rs:type>Invocation error</rs:type>
<rs:message>No operation has been invoked</rs:message>
<rs:description>The value of the input parameter is not valid</rs:description>
</rs:fault>
</format>
<args/>
</payloadFactory>
<respond/>
</default>
And the fault response
{"fault":{"code":-1,"type":"Invocation error","message":"No operation has been invoked","description":"The value of the input parameter is not valid"}}
You can find other scenarios here
http://harshcreationz.blogspot.com/2016/02/common-and-error-handling-sequences.html

This should work.
<payloadFactory media-type="json">
<format>
{
"error":"true",
"message":"error case"
}
</format>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2"/>
<respond/>

Nits
The error response as comments "no response from server", I receive it when I call the api from the test console that has the API Manager.
You can see this link
API Console Issue
To validate the response you expect.
Try calling from another tool such as SOAP UI or Postman, in my case I receive a fault response message with the structure defined.
This is the call from the console API
curl -X GET --header 'Accept: application/xml' --header 'Authorization: Bearer 465f1385-a120-3c19-ad22-c3057e744a3b' 'https://169.254.193.10:8252/getById/1.0.0/getEmployeeXML?Id=5'
For the call from another client in the header pass these values you have in the api call
Accept: application/json
Authorization: Bearer 465f1385-a120-3c19-ad22-c3057e744a3b'

Related

WSO2 change reply to send to the caller

Sorry for my English, I'm using Google Translate to help myself.
I'm writing an API call to a web service. The call is ok and the api returns the response to the caller service, but the client wants that the output of the end-point must be changed from WSO2.
I added this outSequence to the api but the return is a returncode 202 without body.
Can someone help me please?
<outSequence>
<sequence key="">
<payloadFactory media-type="json">
<format>
{ "status": "1",
"message": $2
}
</format>
<args>
<arg evaluator="xml" expression="get-property('ERROR_CODE')"/>
<arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
<arg evaluator="xml" expression="get-property('ERROR_DETAIL')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<send/>
</sequence>
</outSequence>
I think you should try something like this instead
<inSequence>
<sequence key="">
<payloadFactory media-type="json">
<format>
{ "status": "1",
"message": $2
}
</format>
<args>
<arg evaluator="xml" expression="get-property('ERROR_CODE')"/>
<arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
<arg evaluator="xml" expression="get-property('ERROR_DETAIL')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<send/>
</inSequence>
<outSequence>
<property expression="json-eval($)" name="body-before-aggreg" scope="default" type="STRING"/>
<aggregate>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<!--get back from send body here in outsequence!-->
<respond/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence>
<log level="custom">
<property name="text" value="An unexpected error occured for service"/>
<property expression="get-property('ERROR_MESSAGE')" name="message"/>
</log>
<respond/>
</faultSequence>
</resource>
</api>
please note that when you use send -> response messages will go through the Out mediator.

WSO2 EI 6.6.0 Class Mediator not being able to use SOAP call return content

I have the following API in EI 6.6.0:
<?xml version='1.0' encoding='UTF-8'?>
<api xmlns="http://ws.apache.org/ns/synapse" name="sample" context="/sample">
<resource methods="POST">
<inSequence>
<payloadFactory media-type="xml">
<format>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<P xmlns="http://tempuri.org/">
<P1>$1</P1>
<P2>$2</P2>
<P3>$3</P3>
</P>
</soap:Body>
</soap:Envelope>
</format>
<args>
<arg evaluator="json" expression="$.p1" />
<arg evaluator="json" expression="$.p2" />
<arg evaluator="json" expression="$.p3" />
</args>
</payloadFactory>
<log level="full" />
<property name="Content-Type" value="text/xml;charset=UTF-8" scope="axis2"/>
<header name="Accept" scope="transport" value="text/xml"/>
<call>
<endpoint>
<wsdl Action="name_of_the_action" service="name_of_the_service" port="name_of_soap_port" uri="http://<ip>/path?WSDL" />
</endpoint>
</call>
<class name="my_mediator_package"></class>
<log level="full" />
<payloadFactory media-type="xml">
<format>
<retorno xmlns="">
<msg>$1</msg>
</retorno>
</format>
<args>
<arg evaluator="xml" expression="get-property('property_set_on_mediator')" />
</args>
</payloadFactory>
<property name="messageType" value="application/xml" scope="axis2" type="STRING" />
<respond />
</inSequence>
<outSequence>
</outSequence>
<faultSequence>
<property name="text" value="An unexpected error occured"/>
<property name="message" expression="get-property('ERROR_MESSAGE')"/>
<payloadFactory media-type="xml">
<format>
<error xmlns="">
<msg>$1</msg>
</error>
</format>
<args>
<arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<respond/>
</faultSequence>
</resource>
</api>
my mediate method content:
public boolean mediate(MessageContext synCtx) {
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) synCtx)
.getAxis2MessageContext();
try {
// Getting the json payload to string
String jsonPayloadToString = JsonUtil.jsonPayloadToString(((Axis2MessageContext) synCtx)
.getAxis2MessageContext());
System.out.println("original payload : \n" + jsonPayloadToString + "\n");
I'm not being able to use the return from my SOAP call in my mediator so I can work on it.
When I run the API I get the following from my mediator code:
original payload:
{}
Is there a way so I can obtain the SOAP call returned envelope and use it in my mediator?
The JSON payload is coming as empty because you are calling a SOAP backend and getting a SOAP payload. You can use synCtx.getEnvelope() in your mediator to get the SOAPEnvelope from the response.
1- make sure the json payload is there. So, log the json properties inside your inSequence.
2- I'm not being able to use the return from my SOAP call in my mediator so I can work on it. you can see the response payload in your outSequence which currently is doing nothing.
3- According to your scenario which is simply calling a SOAP webservice, you do not need a class mediator. In other words, when you do not need manipulating the initial payload and then pass it to the destination service, logically implementing your own class mediator benefits you nothing.
Also, there are quite number of samples in https://docs.wso2.com/display/EI611 which will help you.
Please let me know if your problem is solved.

Send SMS twilio by postman through wso2

I want to Send SMS twilio by postman through Wso2 ESB , the body , to and from parameters submitted through postman to wso2 sequence , I'm trying to do it by payloadFactory but it does not work , it said :
<TwilioResponse>
<RestException>
<Code>21602</Code>
<Message>Message body is required.</Message>
<MoreInfo>https://www.twilio.com/docs/errors/21602</MoreInfo>
<Status>400</Status>
</RestException>
I'm using https://api.twilio.com/2010-04-01/Accounts/AC*****************/Messages
as endpoint to send it to Twilio
my sequence :
<property expression="json-eval($.Body)" name="Body" scope="default"
type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="json-eval($.To)" name="To" scope="default"
type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="json-eval($.From)" name="From" scope="default"
type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<payloadFactory media-type="json">
<format> { "Body": $1, "From": $2 ,"To": $3 } </format>
<args>
<arg evaluator="xml" expression="get-property('Body')"
literal="false" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="get-property('From')"
literal="false" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="get-property('To')"
literal="false" xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
<call>
<endpoint key="twill2"/>
</call>
<send/>
and my postman request :
{
"Body":"hi dear",
"To":"+(***) *******",
"From":"+1 *******"
}
We have observed that in some cases even though the body is present in the request endpoints returning this error. This is due to the additional headers present or absence of some headers. Can you please try adding the following properties prior to the endpoint call
<property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/>
<property name="setCharacterEncoding" scope="axis2" value="false"/>
<property name="DISABLE_CHUNKING" scope="axis2" value="true"/>
<property name="ContentType" scope="axis2" value="application/json"/>
You can refer to the documentation 1, [2], [3], [4] for additional details on the above properties.
1-https://docs.wso2.com/display/EI660/Generic+Properties#GenericProperties-TRANSPORT_HEADERS
[2]-https://docs.wso2.com/display/EI6xx/Axis2+Properties#Axis2Properties-setCharacterEncoding
[3]-https://docs.wso2.com/display/EI660/HTTP+Transport+Properties#HTTPTransportProperties-DISABLE_CHUNKINGDISABLE_CHUNKING
[4]-https://docs.wso2.com/display/EI660/Generic+Properties#GenericProperties-ContentType
Updated
Can you enable wire in ESB server and attach logs when you invoke the endpoint directly. Refer to the blog [5] on enabling wire logs. Also please attach the curl command of the postman request. You can obtain this by selecting the code button in postman and selecting curl.
[5]-http://lakshanigamage.blogspot.com/2015/03/how-to-enable-wire-logs-in-wso2-esbapim.html

Call multiple sequences in paralell and merge in payloadfactory

I have an endpoint in wso2 integrator, wich receive some parameters, call some rest apis, and produce a new response.
I created a sequence for each rest api call, wich will get the properties and make the specific call. Then with a script mediator, i'm creating a new payload with the response, and putting it in a property. Example: myResponseA, myResponseB, myResponseC.
My main endpoint have an IN sequence with only a clone mediator and a loopback tag. The clone mediator have a target for each sequence described above, like:
<clone continueParent="false" sequential="true">
<target sequence="mySequenceA">
</target>
<target sequence="mySequenceB">
</target>
</clone>
<loopback />
My main endpoint have an OUT sequence with a payloadFactory and a send tag, like:
<payloadFactory media-type="json">
<format>
<![CDATA[
{
"myResponseA": $1,
"myResponseB": $2
}
]]>
</format>
<args>
<arg expression="get-property('myResponseA')"/>
<arg expression="get-property('myResponseB')"/>
</args>
</payloadFactory>
<property name="HTTP_SC" scope="axis2" type="STRING" value="200"/>
<send/>
The problem is, the OUT sequence is called multiple times, one for each sequence in Clone mediator.
I tried to use the Aggregate mediator with no luck, 'coz my apis is restful and i don't know how to use the aggregate expression. I dont even need it, because i put the responses in different properties and read it in my payloadFactory.
How to execute my OUT sequence only one single time when all my sequences return in clone mediator? or there is another mediator i should use?
Obs.: I have to call those apis in parallel, because each one will take some time, and i will call 5~10 each time.
Can you try this as a startup :-D
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="PoCCloneAggregate"
transports="http"
startOnLoad="true"
statistics="enable"
trace="enable">
<description/>
<target>
<inSequence>
<property name="enclosing_element" scope="default">
<result xmlns=""/>
</property>
<clone continueParent="false" sequential="true">
<target>
<sequence>
<log level="custom">
<property name="CLON" value="clon 1"/>
</log>
<payloadFactory media-type="json">
<format>
{"data":
{"temperatura":"10",
"id":"1"}}
</format>
<args>
</args>
</payloadFactory>
<loopback/>
</sequence>
</target>
<target>
<sequence>
<log level="custom">
<property name="CLON" value="clon 2"/>
</log>
<payloadFactory media-type="json">
<format>
{"data":
{"temperatura":"20",
"id":"2"}}
</format>
<args>
</args>
</payloadFactory>
<loopback/>
</sequence>
</target>
<target>
<sequence>
<log level="custom">
<property name="CLON" value="clon 3"/>
</log>
<payloadFactory media-type="json">
<format>
{"data":
{"temperatura":"30",
"id":"3"}}
</format>
<args>
</args>
</payloadFactory>
<loopback/>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<log level="full"/>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete expression="$body/jsonObject" xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" enclosingElementProperty="enclosing_element">
<log level="custom" separator=",">
<property name="MessageFlow" value="======================= Respuestas Agregadas. ==============="/>
</log>
<log level="full" separator=","/>
<send/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence/>
</target>
</proxy>
You have to use aggragate mediator, the goal is to route each response to a single sequence containing this aggregate.
For example, if you use send mediator inside mySequenceA and mySequenceB, define the "receive" attribute to route the response in a dedicated sequence with <send receive="myResponseSequence"> (the same "myResponseSequence" must be used in mySequenceA and B).
If you use call mediator, then call a dedicated sequence with <sequence key="myResponseSequence"> (the same "myResponseSequence" must be used in mySequenceA and B)
inside myResponseSequence, use aggregate mediator :
the completeCondition can be let to default, the ESB will wait to receive the same number of response than the number of targets in your clone mediator. It gives you someting like :
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
the onComplete contains the mediation sequence that will be executed as soon as all the responses will be there : this sequence must contain the send mediator that will send a single response to the caller. The "expression" attribute on this "onComplete" node will contain an xpath that tell which node from the response must arrive inside the onComplete sequence.
inside the onComplete sequence, you can use payloadMediator to compose your single response
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//values">
<payloadFactory media-type="xml">
<format>
<myCustomResponse>
<result>$1</result>
</myCustomResponse>
</format>
<args>
<arg evaluator="xml" expression="//values"/>
</args>
</payloadFactory>
<send/>
</onComplete>
The fact that your api is restful should not be a problem with aggregate mediator. Perhaps the format is json and not xml : use json-eval if you want for the xpath or media-type=json" inside payloadFactory

What is the Use of CallOut Mediator in WSO2ESB 4.7.0

I am using wso2esb4.7.0.i am working with different operations in single proxy i have found one example blog and i go through that.But i am not so clear about that blog my proxy is like this
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<log level="full">
<property name="M1" value="***************HITTING Transaction PROXY****************"/>
</log>
<property name="id" expression="//id/text()"/>
<property name="name" expression="//name/text()"/>
<payloadFactory media-type="xml">
<format>
<p:my_insert xmlns:p="http://ws.wso2.org/dataservice">
<xs:id xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:id>
<xs:name xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:name>
</p:my_insert>
</format>
<args>
<arg expression="get-property('id')" evaluator="xml"/>
<arg expression="get-property('name')" evaluator="xml"/>
</args>
</payloadFactory>
<callout serviceURL="https://localhost:9445/services/DTPDS/" action="urn:my_insert">
<source xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
<target xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
</callout>
<payloadFactory media-type="xml">
<format>
<p:pos_insert xmlns:p="http://ws.wso2.org/dataservice">
<xs:id xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:id>
<xs:name xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:name>
</p:pos_insert>
</format>
<args>
<arg expression="get-property('id')" evaluator="xml"/>
<arg expression="get-property('name')" evaluator="xml"/>
</args>
</payloadFactory>
<callout serviceURL="https://localhost:9445/services/DTPDS/" action="urn:pos_insert">
<source xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
<target xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
</callout>
<log level="full>
<property name="message" value="working"/>
</log>
<inSequence>
In callout meditor above Service url for hitting the endpoint and action is about endpoint operation But What is the use of
SOURCE and TARGET i tried to receive the endpoint response in to this source as well target also but i am unable to get response then what is the use of both
and how i am send my response to my client it means where can i get this response where i need to define my receive sequence Please refer me any clear explanation blog
'source' specifies the payload for the request message using an XPath expression or a registry key. The 'target' specifies a node at which the resulting payload(response) will be attached in the current message context.
By specifying as given in your sample config, response will be attached as the first child of the SOAP message body in message context.
The difference between callout mediator and send mediator is that callout mediator will return the response to the same sequence by doing a blocking call. In send mediator response is returned to the OutSequence in where you can send it back to the client.
So in here you can use the Send mediator (end of the inSequence) in order to send the message to the OutSequence. Then again do a send inside the outSequence to make it returned to the client.
ex:
add Below configs to end of the inSequence
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>
Then inside outSequence, again do a send.
<outSequence>
<send/>
</outSequence>