Cannot send request in mediation synapse in wso2 apim - wso2

We have two ways to send requests in wso2 APIM:
1- send mediator
2- call mediator
Unfortunately, I cannot use any of these mediators!
for example this request: http://jsonplaceholder.typicode.com/posts/
I need this approach for get token from a server and then use it in payload of main request for authentication.
could anyone help me please?! :)
I didn't get any error or special log!
<log level="custom">
<property name="text" value="###############################33"/>
</log>
<call blocking="false">
<endpoint>
<http method="GET" uri-template="http://jsonplaceholder.typicode.com/posts/"/>
</endpoint>
</call>
<log level="custom">
<property name="text" value="###############################"/>
</log>

You could find related blogs "WSO2 API Manager & OAuth2 Protected Endpoint" and answer to this question
The idea is to
call the token endpoint with the appropriate grant type(usually client secret grant is used for system to system calls).
Then extract the token using the script mediator
Then use the that token to call the API attaching the token to "Authorisation Bearer:" header.
Please give this a try.

Let's use the below properties before the call mediator. If your response is not a json payload, you need to set the expected payload content type to the ContentType and messageType properties.
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="ContentType" scope="axis2" value="application/json"/>
<property name="messageType" scope="axis2" value="application/json"/>
After adding the above properties into the sequence, it should look like the below.
<sequence>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="ContentType" scope="axis2" value="application/json"/>
<property name="messageType" scope="axis2" value="application/json"/>
<call blocking="true">
<endpoint>
<http method="GET"
uri-template="http://www.mocky.io/v2/5c9ddf51330000b12c3f253a"/>
</endpoint>
</call>
</sequence>

Related

Unable to get the response from the API

Scenario
I'm sending a request payload to the API that further calls the SMS service provider in the in-sequence flow, I need to share back the response from the SMS service provider as it is. The API works fine and I do receive SMS on phone but I'm unable to share back the response from the service provider in the out sequence flow.
The response body from my SMS service provider is actually text as shown:
The Response header of SMS Service Provider looks like this:
API
<?xml version="1.0" encoding="UTF-8"?>
<api context="/mobilink" name="MobilinkSmsApi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/send">
<inSequence>
<property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/>
<property description="username" expression="json-eval($.username)" name="uri.var.username" scope="default" type="STRING"/>
<property description="password" expression="json-eval($.password)" name="uri.var.password" scope="default" type="STRING"/>
<property description="to" expression="json-eval($.to)" name="uri.var.to" scope="default" type="STRING"/>
<property description="from" expression="json-eval($.from)" name="uri.var.from" scope="default" type="STRING"/>
<property description="message" expression="json-eval($.message)" name="uri.var.message" scope="default" type="STRING"/>
<log level="full"/>
<call>
<endpoint>
<http method="post" statistics="enable" trace="enable" uri-template="https://coXXXXX.XXXX.com/sendsms_url.html?Username={uri.var.username}&Password={uri.var.password}&From={uri.var.from}&To={uri.var.to}&Message={uri.var.message}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</inSequence>
<outSequence>
<log category="TRACE" level="full"/>
<property description="Content-Type" name="Content-Type" scope="default" type="STRING" value="text/html"/>
<property name="messageType" scope="axis2" type="STRING" value="text/html"/>
<respond/>
</outSequence>
<faultSequence>
<log category="ERROR" level="full"/>
</faultSequence>
</resource>
</api>
Question
My Question is how to share back the response from the service provider in the out sequence? I tried to use property with value text/html and even used content-type as text/html but It didn't worked.
There are two ways to achieve this. either one of below mentioned way you can follow
place <respond/> after <call> mediator
Use <Send> mediator instead of <call>, so that flow will come from insequence to outsequence where you already placed <respond/> to send back message to client
The issue got resolved when I placed the mediator in the inSequence flow.
previously I was placing the mediator in the outSequence

Property mediator is disappearing in WSO2 EI 6.6

I'm trying to send the token before the endpoint but it's disappearing when it's deployed in the server and I even try to the pass the token within the endpoint properties but it's not accepting and thrown error like Invalid token, please help me to sort this out.
<log level="custom">
<property name="uri.var.apiurl ::::::::::::::::::: " expression="$ctx:uri.var.apiurl"/>
<property name="Authorization ::::::::::::::::::: " expression="$trp:Authorization"/>
</log>
<call description="VB iAppraisal Endpoint">
<property name="Authorization" scope="transport" value="Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjllMDA1MGQ4ZDFlNmZlMTYzMjllMGViYTY1MmE4NDBhMTZhMDUzZjQ3MWU0OTA4MmE0Y2ZkOGI2NTZhYjU3N2NkMmEwNTUxNjhkYzVhMjRiIn0.eyJhdWQiOiI3MjUiLCJqdGkiOiI5ZTAwNTBkOGQxZTZmZTE2MzI5ZTBlYmE2NTJhODQwYTE2YTA1M2Y0NzFlNDkwODJhNGNmZDhiNjU2YWI1NzdjZDJhMDU1MTY4ZGM1YTI0YiIsImlhdCI6MTY1MDk2ODgzMiwibmJmIjoxNjUwOTY4ODMyLCJleHAiOjE2ODI1MDQ4MzIsInN1YiI6IjU3NCIsInNjb3BlcyI6W119.BUyx65owuErEmx57_N-FC4kT_QvPQ01pvof_308hjWHPbfrajajs2oGJx0hTuztQUT5xTKqMEV9pFHfdUKM93VWTBBCMFrbP9Qg03dq1Se9fbXGJ5EkmRiAy9qJ2WCiMs2sj6sN3H7_aWxn0D6u9kbfymzRUdw3pP9KT0L0hl03RRAliW0JpVv6qJgog2bvCJni_BsM5kt84dXFohbEtRqas40bYCd-VHqy-pxlVbq6-y27OF5XC-qcWRxT78iXG2P9joULCZKTHINUPigpT2h8-QA8nPakmDflEgLScG1yAKlcgDY1aVLEZYOblkMryoITQ1bfGck_jdq_hiCu5qtz1JEhTyYXpv3RxJ_8Bnp4Do_PKfMUbqxNaDbZr75sr83HTWlcsBcPYIVG3xXRAXcB4rRKB25NitdGBkg4zqcc9SiVqBgxT2FNWEjugs-tanNjcNODX_sradOQ-7RLlcTy7NRLqa3lUyNSBpow__X5DjJpGRQoym-9j3PRQGQGOQgNImuplYQ066n4W-TzradcaxLm0oCaSqlfZ9Ozn-9as5NHMdUlNYHpOb1aAi5Qxg0JtVvdSKAYiWpwmEzBAkTm3PWMRwQpXHMqGNgkpibwI3QcqY5IrPB1ZZ0xnZ-_bOHbpFLxgAMGGBRkIBVIqPmxCxqZz06TsQWGAF9cZ12c "/>
<endpoint key="iAppraisal"/>
</call>
Don't wrap <property name="" ... /> inside <call > mediator. It should be before call endpoint like below:
<property name="Authorization" scope="transport" value="Bearer eyJ0eXAiOiJK /.../ Z12c"/>
<call description="VB iAppraisal Endpoint">
<endpoint key="iAppraisal"/>
</call>
Or optionally you can put that inside Endpoint definition.

WSO2 Integrator: REST API GET Request missing response body

I am using WSO2 Integrator 6.6.0 to make a blocking HTTP GET to a REST API that returns a JSON response (HTTP 200 OK).
But I never see the response body inside my sequences. I am not sure what I am doing wrong, having exhausted all available documentation and other threads.
Sequence doing the call (simplified to anonymize), which logs the response afterwards:
<!-- Remove XML body as not needed for GET request -->
<payloadFactory media-type="json">
<format></format>
<args></args>
</payloadFactory>
<header name="Accept" value="application/json" scope="transport"/>
<property name="NO_ENTITY_BODY" value="true" scope="axis2" type="BOOLEAN" />
<call blocking="true">
<endpoint>
<http method="GET" uri-template="http://my-api/order-status">
</endpoint>
</call>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<log level="full">
<property name="response-log" value="Received response"/>
<property expression="$body" name="response-body"/>
<property expression="json-eval($)" name="json-eval-body"/>
</log>
This results simply into a log line - with no response body at all!
INFO {org.apache.synapse.mediators.builtin.LogMediator} - To:
http://my-api/order-status, WSAction: urn:mediate, SOAPAction:
urn:mediate, MessageID:
ID:414d51204343494153303131202020209ca4175f28ac422e, Direction:
response, response-log = Received response, response-body =
<soapenv:Body
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"></soapenv:Body>,
json-eval-body = {}, Payload: {}
I can see the request in my API application and I can also see what it correctly returns a response body in its logs. Also, using Postman to do the same request I receive the following JSON response with 200 OK and Content-Type appication/json:
{
"order_status": "NOT_FOUND"
}
Inside WSO2 I do not see anything! I want to be able to convert the response into XML format.
What could be wrong?
Before making a REST call, it is necessary to remove the headers from the main call.
Put this snippet before the call mediator:
<property name = "FORCE_HTTP_CONTENT_LENGTH" scope = "axis2" type = "STRING" value = "true" />
<property action = "remove" name = "REST_URL_POSTFIX" scope = "axis2" />
<property action = "remove" name = "TRANSPORT_HEADERS" scope = "axis2" />
As I understand it should solve.
Can you modify the NO_ENTITY_BODY property as follows and try this mediation again.
<property name="NO_ENTITY_BODY" action="remove" scope="axis2"/>
Having simplified this configuration for this question, I had missed that having the following property set in my proxy service:
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
Means that WSO2 is ignoring the response from the API. Removing this property resolved the issue for the following config:
<header name="Accept" value="application/json" scope="transport" />
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<call blocking="true">
<endpoint key="conf:/endpoints/FX_TRADING_API_ORDERSTATUS.xml"/>
</call>

Invoking RESTful service from WSO2 ESB using method POST

I have a simple RESTful service that I want to expose as SOAP based Web Service using WSO2 ESB.
My simple RESTful service can be invoked like http://<<my system>>:8080/myapp/person/read
As response, I get JSON data of the Person entity.
Problem: I am not able to pass parameters to the RESTful service. I am to strip the param value from the SOAP input, but don't know how to pass it to my RESTful; service using ESB.
I have configured the following in WSO2 ESB
<proxy xmlns="http://ws.apache.org/ns/synapse" name="PersonProxy" transports="https,http" statistics="enable" trace="enable" startOnLoad="true">
<target>
<inSequence>
<property xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" name="PERSON_ID" expression="//soapenv:Body/person/id"/>
<log level="full">
<property name="PERSON_ID" expression="get-property('PERSON_ID')"/>
</log>
<filter xpath="//person">
<then>
<property name="REST_URL_POSTFIX" value="read" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
<property name="id" expression="get-property('PERSON_ID')" scope="axis2" type="STRING"/>
<property name="ContentType" value="application/x-www-form-urlencoded" scope="axis2" type="STRING"/>
</then>
<else/>
</filter>
<send>
<endpoint>
<address uri="http://<<my system>>:8080/myapp/person" format="rest"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description></description>
</proxy>
My SOAP request looks like following
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<person>
<id>3</id>
</person>
</soapenv:Body>
</soapenv:Envelope>
I have another RESTful service with GET method and id as part of the URL itself, and that works fine. The ESB config looks like
<property name="REST_URL_POSTFIX" expression="get-property('PERSON_ID')" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="GET" scope="axis2" type="STRING"/>
<endpoint>
<address uri="http://<<my system>>:8080/cfs/person" format="rest"/>
</endpoint>
Appreciate any pointers or help.
If your service can be invoked as http://<<my system>>:8080/myapp/person/id, you can read the id from the SOAP request and send it using "REST_URL_POSTFIX" property as below.
<property name="REST_URL_POSTFIX" expression="//person/id" scope="axis2" type="STRING"/>
Take a look at this example which implements a similar scenario.
You can also try using the HTTP Endpoint which is new in ESB 4.7.0. You can define a URI Template much like in the REST API. Populating the template variables is done via property mediators - so anything you can do with a property mediator can be used to define the endpoint URL during mediation run time.

WSO2 ESB overwrites a ContentType property

I am working on the WSO2 ESB Proxy service, which involves exposing the internal RESTful service via SOAP endpoint on the ESB.
My RESTful service requires Content-type = "application/rdf+xml". I tried setting it using all 3 properties mentioned in the documentation: messageType, ContentType and CONTENT_TYPE. However, the request Content-type still remains "application/xml".
Here is an excerpt from my sequence that calls REST service:
<property xmlns:ns="http://org.apache.synapse/xsd" name="REST_URL_POSTFIX" value="/record/12345" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="PUT" scope="axis2" type="STRING"/>
<property name="messageType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="ContentType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="CONTENT_TYPE" value="application/rdf+xml" scope="axis2" type="STRING"/>
<send>
<endpoint name="CQ">
<address uri="http://my_url" format="pox">
</address>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Authorization" expression="fn:concat('Basic ', base64Encode('username:password'))" scope="transport"/>
<property name="OSLC-Core-Version" value="2.0" scope="transport"/>
<property name="Accept" value="application/rdf+xml" scope="transport"/>
</endpoint>
</send>
I tested it with TCPMon and no matter what Content-type property I use, request still contains "application/xml".
Please advice.
Can you try WSO2 ESB 4.7.0 with following configuration? Note that, I have changed the address format from "pox" to "rest"
<property xmlns:ns="http://org.apache.synapse/xsd" name="REST_URL_POSTFIX" value="/record/12345" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="PUT" scope="axis2" type="STRING"/>
<property name="messageType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="ContentType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="CONTENT_TYPE" value="application/rdf+xml" scope="axis2" type="STRING"/>
<send>
<endpoint name="CQ">
<address uri="http://my_url" format="rest">
</address>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Authorization" expression="fn:concat('Basic ', base64Encode('username:password'))" scope="transport"/>
<property name="OSLC-Core-Version" value="2.0" scope="transport"/>
<property name="Accept" value="application/rdf+xml" scope="transport"/>
</endpoint>
</send>
These are the http headers sent now (captured from tcpmon)
PUT /record/12345 HTTP/1.1
Cookie: region1_configure_menu=none; region3_registry_menu=none; region4_monitor_menu=none; region5_tools_menu=none; JSESSIONID=54D2911FCD5559C6B2F723E7C6FA9B44; requestedURI="../../carbon/service-mgt/index.jsp?region=region1&item=services_list_menu"; current-breadcrumb=manage_menu%2Cservices_menu%2Cservices_list_menu%23
Authorization: null
OSLC-Core-Version: 2.0
Content-Type: application/rdf+xml
Accept: application/rdf+xml
Transfer-Encoding: chunked
Host: www.foo.com:8080
Connection: Keep-Alive
User-Agent: Synapse-PT-HttpComponents-NIO
In the configuration you have attached, you have specified the format of the address uri as "pox" .
<address uri="http://my_url" format="pox">
This will be the reason that you are getting content-type as application/xml always. Please remove this attribute and try. It should be
<address uri="http://my_url">
If you still see the issue, then try to switch to the NHTTP transport as suggested by RaviU. For that, you can first backup the axis2.xml (ESB_HOME/repository/conf/axis2/axis2.xml) as axis2_back.xml and then rename the axis2_nhttp.xml file (same location) as axis2.xml.
Can you set the content type property like this;
<property name="Content-Type” value="application/rdf+xml" scope="transport"/>
Please remove other content-type properties..
If you define like this;
[1]<property name="messageType" value="application/rdf+xml" scope="axis2" type="STRING"/>
[2]<property name="ContentType" value="application/rdf+xml" scope="axis2" type="STRING"/>
[1] for, to select messageformatter
[2]for, to select message builders
Edit;
try like this
<inSequence>
<log level="custom">
<property name="in seq --------------of proxy" expression="$trp:Content-Type"/>
</log>
<property name="messageType"
value="application/json"
scope="axis2"
type="STRING"/>
<property name="Content-Type"
value="application/json"
scope="transport"
type="STRING"/>
<log level="custom">
<property name="in seq --------------of proxy" expression="$trp:Content-Type"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:5555/com"/>
</endpoint>
</send>
Sometimes, you have to enable those message formatters in axis2.xml before using them.
Check this article out. It may help if you haven't done so yet.
http://wso2.com/library/articles/axis2-configuration-part2-learning-axis2-xml#mf