Month: September 2015

How to read dynamic query parameter in ESB/APIM synapse.

Following way you will be able to get the dynamic parameters
For e.g
1. My api has the following url  http://xxxx8243/uridynamic/1
2. and i have added a GET resource(uri-template) to api  /add?*
that means there can be zero or many query parameters.
3. Now my get request takes following format
4. in the sequence you can read the value of ‘a‘ and ‘b‘ as using $url
if a and b is not present in the url value of SYMBOL and value of SYMBOL2 will have
null value.
<log level=”custom”>
            <property name=”SYMBOL” expression=”$url:a“></property>
            <property name=”SYMBOL2″ expression=”$url:c“></property>
 </log>
Advertisements

Wso2 ESB/APIM add query parameter to endpoint

Lets say there is a http endpoint http://localhost:8080/restapi defined in a api and want to add query parameter in sequence level before invoking the endpoint.

i.e   http://localhost:8080/restapi?id=2&name=admin&role=admin

By using Property “REST_URL_POSTFIX” this can be achieved as follow.


<?xml version="1.0" encoding="UTF-8"?>
<sequence
 xmlns="http://ws.apache.org/ns/synapse" name="admin--test:v1--In">
 <log level="full">
 <property name="IN_MESSAGE" value="IN_MESSAGE"/>
 </log>
 <property name="id" value="2"/>
 <property name="name" value="admin"/>
 <property name="role" value="admin"/>
 <property name="REST_URL_POSTFIX" expression="fn:concat('?id=',$ctx:id,'&amp;name=',$ctx:name,'&amp;role=',$ctx:role)" scope="axis2"/>
 <endpoint
 xmlns="http://ws.apache.org/ns/synapse" name="HTTPEndpoint">
 <http uri-template="http://localhost:8080/restapi" method="GET"></http>
 </endpoint>
</sequence>

How to access wso2 admin service from jaggery

This post explain how to access wso2 admin service from jaggary code.

By default admin services are hidden from consumers in wso2 products. Discovering the admin service wslds of a product can be found here[1]

As an example we are going to see how to add a role to a user in any wso2 product using admin service.

1 . Create a role called “subsciber”  via admin console

2. Create a user called “jena” via admin console

3. Assign the role created in 1 to user created in 2 via admin service call.

(for this post assume step 1 and 2 are done in carbon super tenant)

For this particular scenario we need use https://localhost:9443/services/UserAdmin?wsdl. In the wsdl there is a operation called “addRemoveRolesOfUser”  which is used to add or remove roles of a user.

In order to invoke this method in jaggery code we need to know
1. Endpoint of the service
2. Request payload
3. Admin user credential of the tenant where particular user exists(admin service is protected with basic authentication)
Both can be taken from the wsdl manually or taken by creating new soap ui project using this wsld.

add_role_soapui

jaggery code – User WSRequest object[2] to send the request


<%
 var ws = require("ws");
 var version = new ws.WSRequest();
 var options = new Array();
 options.usesSOAP = 1.2;
 options.mep = "in-only";
 options.action = "urn:addRemoveRolesOfUser";
 var log=new Log();
 var username = "jena"

 var paylod = '<xsd:addRemoveRolesOfUser xmlns:xsd="http://org.apache.axis2/xsd"><xsd:userName>'+username+'</xsd:userName><xsd:newRoles>subscriber</xsd:newRoles><xsd:deletedRoles>?</xsd:deletedRoles></xsd:addRemoveRolesOfUser>';
var result;
try {
 version.open(options, "https://localhost:9443/services/UserAdmin.UserAdminHttpsSoap12Endpoint", false, "admin", "admin");
 version.send(paylod);
 } catch (e) {
 log.error(e.toString());
 }
%>

  1. https://docs.wso2.com/display/AM160/WSO2+Admin+Services
  2. http://jaggeryjs.org/documentation.jag?api=ws

How to do a POST/PUT request with no body in WSO2 ESB?

ESB message flow will go through builders and formatters when ESB is configured to use NHTTP transport or pass-thru transport with content aware mediators used[1]. In both cases ESB will build the message body. So when come to POST/PUT request by default ESB expects a message body to be present in the request to send to the backend. So when there is POST/PUT request without body request will hang in the server.

This default behavior can be changed by setting the property

<property name="FORCE_POST_PUT_NOBODY" value="true" scope="axis2" type="BOOLEAN" />

Once this property is set ESB can send the request to back end even though there is no body with request. If pass-thru transport is used and there is no content aware mediators used in proxy/api message flow will not hit the builders and formatters. That means ESB will not deal with message body , it will pass what ever come to the server as it is to back-end. So in that case no need to set this special property.

  1. POST request no (body passthru transport and content aware mediator(log full) is used )- request hangs
[2015-09-05 17:45:40,075] DEBUG - wire >> "POST /test/1/preq HTTP/1.1[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Host: localhost:8280[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Connection: keep-alive[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Content-Length: 0[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/41.0.2272.76 Chrome/41.0.2272.76 Safari/537.36[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Cache-Control: no-cache[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Authorization: Bearer 84d2c7f333f93c27952ec33be2c0e5b5[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Accept: */*[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Accept-Encoding: gzip, deflate[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Accept-Language: en-US,en;q=0.8[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "Cookie: region4_monitor_menu=visible; region1_identity_entitlement_menu=visible; region3_metadata_menu=visible; region1_manage_menu=visible; region3_registry_menu=visible; menuPanel=visible; menuPanelType=main; i18next=en-US[\r][\n]"
[2015-09-05 17:45:40,076] DEBUG - wire >> "[\r][\n]"
[2015-09-05 17:45:40,083]  INFO - LogMediator To: /test/1/preq, MessageID: urn:uuid:e00a9af5-d0ec-4c22-9019-8cdae17ac3cb, Direction: request, IN_MESSAGE = IN_MESSAGE, Envelope: 
[2015-09-05 17:46:40,144]  WARN - SourceHandler Connection time out after request is read: http-incoming-1
[2015-09-05 17:46:40,145] DEBUG - wire >> "POST /test/1/preq HTTP/1.1[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "Host: localhost:8280[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "Connection: keep-alive[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "Content-Length: 0[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/41.0.2272.76 Chrome/41.0.2272.76 Safari/537.36[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "Cache-Control: no-cache[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "Authorization: Bearer 84d2c7f333f93c27952ec33be2c0e5b5[\r][\n]"
[2015-09-05 17:46:40,146] DEBUG - wire >> "Accept: */*[\r][\n]"
[2015-09-05 17:46:40,147] DEBUG - wire >> "Accept-Encoding: gzip, deflate[\r][\n]"
[2015-09-05 17:46:40,147] DEBUG - wire >> "Accept-Language: en-US,en;q=0.8[\r][\n]"
[2015-09-05 17:46:40,147] DEBUG - wire >> "Cookie: region4_monitor_menu=visible; region1_identity_entitlement_menu=visible; region3_metadata_menu=visible; region1_manage_menu=visible; region3_registry_menu=visible; menuPanel=visible; menuPanelType=main; i18next=en-US[\r][\n]"
[2015-09-05 17:46:40,147] DEBUG - wire >> "[\r][\n]"
[2015-09-05 17:46:40,150]  INFO - LogMediator To: /test/1/preq, MessageID: urn:uuid:b203f072-b044-41fb-9a96-f8d56cfc0aee, Direction: request, IN_MESSAGE = IN_MESSAGE, Envelope: 
[2015-09-05 17:47:40,213]  WARN - SourceHandler Connection time out after request is read: http-incoming-2
[2015-09-05 17:47:43,509]  WARN - TimeoutHandler Expiring message ID : urn:uuid:24e8733b-3184-4bae-8831-43e1d8366d68; dropping message after global timeout of : 120 seconds
[2015-09-05 17:48:43,510]  WARN - TimeoutHandler Expiring message ID : urn:uuid:4037382a-c498-4377-b599-182095c662f4; dropping message after global timeout of : 120 seconds

2. POST request no body  “FORCE_POST_PUT_NOBODY” is set(passthru transport and content aware mediator(log full) is used )- request doesn’t hang

[2015-08-28 17:21:51,776] DEBUG - wire >> "POST /test/1/preq HTTP/1.1[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Host: xxxxx:8280[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Connection: keep-alive[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Content-Length: 0[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/41.0.2272.76 Chrome/41.0.2272.76 Safari/537.36[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Cache-Control: no-cache[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Authorization: Bearer 1e519d8be6ab6bd12bf3a9378bba646[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Accept: */*[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Accept-Encoding: gzip, deflate[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "Accept-Language: en-US,en;q=0.8[\r][\n]"
[2015-08-28 17:21:51,776] DEBUG - wire >> "[\r][\n]"
[2015-08-28 17:21:51,778]  INFO - LogMediator IN_MESSAGE = IN_MESSAGE
[2015-08-28 17:21:51,779]  INFO - LogMediator To: /test/1/preq, MessageID: urn:uuid:05b53455-6ed1-47f1-aee3-9808fe694328, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><mediate/></soapenv:Body></soapenv:Envelope>
[2015-08-28 17:21:51,781] DEBUG - wire << "POST /post/preq HTTP/1.1[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Accept-Language: en-US,en;q=0.8[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Accept-Encoding: gzip, deflate[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Content-Type: application/x-www-form-urlencoded; charset=UTF-8[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Accept: */*[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Cache-Control: no-cache[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Transfer-Encoding: chunked[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Host: localhost:8080[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "Connection: Keep-Alive[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "0[\r][\n]"
[2015-08-28 17:21:51,781] DEBUG - wire << "[\r][\n]"
[2015-08-28 17:21:51,782] DEBUG - wire >> "HTTP/1.1 200 OK[\r][\n]"
[2015-08-28 17:21:51,782] DEBUG - wire >> "Content-Type: application/xml[\r][\n]"
[2015-08-28 17:21:51,782] DEBUG - wire >> "Content-Encoding: gzip[\r][\n]"
[2015-08-28 17:21:51,782] DEBUG - wire >> "Transfer-Encoding: chunked[\r][\n]"
[2015-08-28 17:21:51,782] DEBUG - wire >> "Server: Jetty(6.1.26)[\r][\n]"
[2015-08-28 17:21:51,783] DEBUG - wire >> "[\r][\n]"
[2015-08-28 17:21:51,783] DEBUG - wire >> "26[\r][\n]"
[2015-08-28 17:21:51,783] DEBUG - wire >> "[0x1f][0x8b][0x8][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0xb3]).I,)-[0xb6]+.MNN-.[0xb6][0xd1][0x87][0xf2][0x1][0xea][0x1a]q[0x6][0x18][0x0][0x0][0x0][\r][\n]"
[2015-08-28 17:21:51,783] DEBUG - wire >> "0[\r][\n]"
[2015-08-28 17:21:51,783] DEBUG - wire >> "[\r][\n]"
[2015-08-28 17:21:51,786] DEBUG - wire << "HTTP/1.1 200 OK[\r][\n]"
[2015-08-28 17:21:51,786] DEBUG - wire << "Access-Control-Allow-Headers: authorization,Access-Control-Allow-Origin,Content-Type[\r][\n]"
[2015-08-28 17:21:51,786] DEBUG - wire << "Access-Control-Allow-Origin: *[\r][\n]"
[2015-08-28 17:21:51,786] DEBUG - wire << "Content-Encoding: gzip[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "Access-Control-Allow-Methods: POST[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "Content-Type: application/xml[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "Date: Fri, 28 Aug 2015 11:51:51 GMT[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "Server: WSO2-PassThrough-HTTP[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "Transfer-Encoding: chunked[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "Connection: keep-alive[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "26[\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "[0x1f][0x8b][0x8][0x0][0x0][0x0][0x0][0x0][0x0][0x0][0xb3]).I,)-[0xb6]+.MNN-.[0xb6][0xd1][0x87][0xf2][0x1][0xea][0x1a]q[0x6][0x18][0x0][0x0][0x0][\r][\n]"
[2015-08-28 17:21:51,787] DEBUG - wire << "0[\r][\n]"
[2015-08-28 17:21:51,788] DEBUG - wire << "[\r][\n]"

But when <property name=”FORCE_POST_PUT_NOBODY” value=”true” scope=”axis2″ type=”BOOLEAN”/>” is set in the synapse config, ESB will set the default content type (application/x-www-form-urlencoded) and do the post/put with no body. We cannot remove the content type completely but we can change the value of it using property.

e.g <property name=”Content-Type” value=”text/plain” scope=”transport”/> will change change the content type to text/plain

  1. http://wso2.com/library/articles/2013/12/demystifying-wso2-esb-pass-thru-transport-part-ii/