Adding http path parameters dynamically in wso2 esb - wso2

We have a proxy service which uses jms transport to receive messages. The messages received need to be sent to a backend REST service using http POST.
The following is done on the messages
xslt transformation to extract specific fields
set message type to application/json
send to the endpoint
The REST service endpoint needs to have a path parameter appended dynamically using one of the values that comes as part of the input message from jms. The url will look like
http://<server-ip>/service/<client>. Here the value for the "client" comes as part of the message.
How can we dynamically add the path param using wso2 esb?

I believe what you are looking for is the REST_URL_POSTFIX property. If you set this property, the value will be appended to the rest endpoint url.
It can be defined as follows with the scope of axis2.
<property name="REST_URL_POSTFIX"
          expression="//client"
          scope="axis2"
         type="STRING"/>
An example on this can be found in this guide, Using REST with a Proxy Service.
EDIT: Following is example using a simple proxy with a POST request using curl. Providing as per the comments. Here, I'm invoking the jaxrs_basic rest service in WSO2 Application Server.
curl -H "Content-Type: application/xml" -H "Accept: application/json" -d "<Customer><name>KasunG</name></Customer>" http://localhost:8281/services/new1/
.
curl -H "Content-Type: application/json" -H "Accept: application/json" -d "{ 'Customer' : { 'name' : 'KasunG' } } " http://localhost:8281/services/new1/
.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="new1"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<property name="REST_URL_POSTFIX"
value="customers"
scope="axis2"
type="STRING"/>
<property name="ContentType" value="text/xml" scope="axis2" type="STRING"/>
<switch source="$axis2:HTTP_METHOD">
<case regex="GET">
<property name="HTTP_METHOD" value="GET" scope="axis2" type="STRING"/>
</case>
<case regex="POST">
<property name="messageType" value="application/json" scope="axis2"/>
<property name="ContentType"
value="application/JSON"
scope="axis2"
type="STRING"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
</case>
<default/>
</switch>
<send>
<endpoint>
<address uri="http://localhost:8888/jaxrs_basic/services/customers/customerservice"
format="rest"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<property name="messageType" value="application/json" scope="axis2"/>
<send/>
</outSequence>
</target>
</proxy>

I think links [1] & [2] will help you to set jms with WSO2 proxy... To dynamically add path param to the url use the link [3], it is for XML configuration file. similar to this you can assign the part of the message to a property add append that to the url...
[1] http://docs.wso2.org/wiki/display/ESB460/Publish-Subscribe+%28Pub-Sub%29+with+JMS
[2] http://wso2.org/library/articles/2011/11/wso2-esb-example-two-wayrequestresponse-semantic-jms
[3] How to dynamically route message in WSO2 ESB based on XML configuration file
Thanks,
Mohan

Related

Cannot send request in mediation synapse in wso2 apim

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>

WSO2 ESB HTTP POST with form data

I have a soap service that I want to turn around and post a message to an external server.
I was able to do this via curl like so:
curl --data-urlencode "filename=data.txt" --data-urlencode "filedir=/home/myfile/in"
--data-urlencode "busproc=MyBP" --data-urlencode "serverip=192.168.1.4"
--data-urlencode"uid=myuserid" --data-urlencode "pwd=mypwd"
http://somelocation.com:8833/webservice/inbound/here
But I can't quite get it working correctly. Here's my proxy service:
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="ExampleHTTPPostWithFormData"
transports="http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log/>
<property name="messageType"
value="application/x-www-form-urlencoded"
scope="axis2"
type="STRING"/>
<property name="HTTP_METHOD" value="post" scope="axis2" type="STRING"/>
<send>
<endpoint>
<address uri="http://somelocation.com:8833/webservice/inbound/here"
format="pox"/>
<property name="uid" value="user"/>
<property name="pwd" value="password"/>
<property name="filedir" value="/home/myfile/in"/>
<property name="busproc" value="myBP"/>
<property name="serverip" value="192.168.1.4"/>
<property name="filename" value="data.txt"/>
</endpoint>
</send>
<log level="full"/>
</inSequence>
</target>
<description/>
</proxy>
The end service seems to only see me posting to the URL (but not the passed in data properties).
Properties are not the way to build the message content. The best way I've found to do it is with a payloadFactory. The message you need to build has a root XML element with one child per form field, and then it seems that Axis2 handles the messageType of application/x-www-form-urlencoded by serialising in the appropriate format. So a minimal change to your proxy would be:
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="ExampleHTTPPostWithFormData"
transports="http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log/>
<property name="messageType"
value="application/x-www-form-urlencoded"
scope="axis2"
type="STRING"/>
<payloadFactory media-type="xml">
<format>
<params xmlns="">
<uid>user</uid>
<pwd>password</pwd>
<filedir>/home/myfile/in</filedir>
<busproc>myBP</busproc>
<serverip>192.168.1.4</serverip>
<filename>data.txt</filename>
</params>
</format>
</payloadFactory>
<send>
<endpoint>
<address uri="http://somelocation.com:8833/webservice/inbound/here"
format="rest"/>
</endpoint>
</send>
<log level="full"/>
</inSequence>
</target>
<description/>
</proxy>
It may also be convenient to add <property name="FORCE_HTTP_1.0" value="true" scope="axis2" type="STRING"/> depending on whether your REST service handles HTTP/1.1.
If you need parameters then you can pass in arguments to the payloadFactory, using the XPath extensions. E.g.
<payloadFactory media-type="xml">
<format>
<params xmlns="">
<uid>user</uid>
<pwd>password</pwd>
<filedir>/home/myfile/in</filedir>
<busproc>myBP</busproc>
<serverip>192.168.1.4</serverip>
<filename>$1</filename>
</params>
</format>
<args>
<arg evaluator="xml" expression="$ctx:filename"/>
</args>
</payloadFactory>
If your sending the SOAP payload in a file you would need to use the VFS transport. Please refer to the following sample on how to use the VFS transport to solve your issue
http://docs.wso2.org/pages/viewpage.action?pageId=26838852
Alternatively you can use SOAPUI or any SOAP client to send the payload directly to the ESB proxy endpoint

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.

ESB doesn't return anything from the GET service failing with NPE

I've configured a proxy service to run some XSBRL validation stuff that accepts a get request amd return XML validation results. Here's proxy service configuration:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="XBRLValidationRESTService" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<log level="full"/>
<property name="REST_URL_POSTFIX" value="/example.xbrl/validation/xbrl?media=xml" scope="axis2"/>
<property name="HTTP_METHOD" value="GET" scope="axis2"/>
<send>
<endpoint>
<address uri="http://localhost:10000/rest/xbrl" format="pox"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full"/>
<send/>
</outSequence>
</target>
<description></description>
</proxy>
In the log file I can see that the underlying service responds with expected response, however the client receives nothing back because ESB fails with NPE for some reason.
Request used from localhost:
curl -k https://localhost:9443/services/XBRLValidationRESTService
Full log: http://pastebin.com/A5jB9wMF
What is the potential reason for that and how that could be fixed.
Thanks,
Vladimir.
Do you run ESB with blocking transport? By default esb uses NIO transport and the port is 8280. your proxy service url, will be;
http://localhost:8280/services/XBRLValidationRESTService
Rather putting log full state, use descriptive logs to identify message paths,

WSO2 ESB - transform a HTTP 202 accepted response

The Endpoint_BPS_CreateCaseService/UpdateCaseService endpoints below both point to one-way BPEL services running on WSO2 BPS. WSO2 BPS returns a HTTP 202 accepted message instantly when they are invoked.
The client application that I am using will throw a fault if it does not get a valid SOAP envelope as a response so I'm going to use a proxy service in ESB to wrap around the BPEL process.
How do I use a WSO2 ESB proxy service to forward a SOAP envelope to Endpoint_BPS_* below and then return a SOAP envelope response to my client app?
I also want to execute the faultSequence "ProcessFault" if either endpoint is unavailable or times out. I previously used the OUT_ONLY to get around the response issue above but it means I can't detect endpoint problems. Unless it is possible to do both somehow?
Another thing I've tried is cloning the message but this was a bit messy.
Any help greatly appreciated
<proxy xmlns="http://ws.apache.org/ns/synapse" name="BPSProxyService" transports="https,http" statistics="disable" trace="enable" startOnLoad="true">
<target faultSequence="ProcessFault">
<inSequence>
<log level="full">
<property name="MESSAGE" value="BEGIN BPSProxyService" />
</log>
<switch source="//*[local-name()='Operation']">
<case regex="create">
<send>
<endpoint key="Endpoint_BPS_CreateCaseService" />
</send>
</case>
<case regex="update">
<send>
<endpoint key="Endpoint_BPS_UpdateCaseService" />
</send>
</case>
</switch>
</inSequence>
<outSequence>
<property name="HTTP_SC" value="200" scope="axis2" />
<class name="esb.mediators.InjectSOAPEnvelope" />
<log level="full">
<property name="MESSAGE" value="END BPSProxyService" />
</log>
<send />
<drop />
</outSequence>
</target>
<publishWSDL key="common/bpsproxyservice/bpsproxyservice.wsdl">
<resource location="schema.xsd" key="common/schema_v2.xsd" />
</publishWSDL>
</proxy>
When you receive a 'HTTP/1.1 202 Accepted' response from your backend like BPS in the outSequence of your Proxy Service, then you need the <property name="SC_ACCEPTED" value="false" scope="axis2"/> statement to modify the '202'-response into something else.
Example:
<property name="SC_ACCEPTED" value="false" scope="axis2"/>
<property name="HTTP_SC" value="200" scope="axis2"/>
<payloadFactory media-type="xml">
<format>
<response>
<result>OK</result>
</response>
</format>
<args/>
</payloadFactory>
<send/>
The response is transformed into 'HTTP/1.1 200 OK' with a response message.
Add the "FORCE_SC_ACCEPTED" parameter with the "OUT_ONLY" in the inSequence of the proxy service as follows.
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"/>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
For more information use the following article:
http://mohanadarshan.wordpress.com/2013/05/05/out_only-scenario-in-proxy-service-wso2-esb/