wso2 esb customURI / serviceURI with expression - wso2

I am trying to implement ESB solution to replace a web-tier part of a complex web-service architecture. The web-tier just receives the request from clients and distributes to a given set of app-tier instances.
Since the end-points are already defined and used by clients, I had to build the ESB proxy using the "CustomURI" approach as described here - http://achala11.blogspot.com/2012/08/access-wsdl-for-customuri-wso2-esb.html - to expose the end-point and wsdl.
Note that ServiceURI only allows to specify a fixed context path (correct me if I am wrong). For example:
If WSDL end-point is http:// localhost:8280/CustomURL/Part1/Part2?wsdl, the corresponding ServiceURI entry is
<parameter name="ServiceURI">/CustomURL/Part1/Part2</parameter>
What I want to use is an expression like this:
<parameter name="ServiceURI">/CustomURL/*</parameter>
to indicate that all requests that starts with /CustomURL in the context path will be handled by the proxy. Inside the proxy, I like to propagate the context URI to the endpoint defined in the send block. I think I found a RESTful way (didn't get it to work completely) of doing what I am trying to do here. As you can see, I can specify a context in the api and then use url-mapping option of resource to route all request to the api block. Later I am trying to use the "http endpoint" approach to construct the endpoint with the contextURI appended.
<api xmlns="http://ws.apache.org/ns/synapse" name="customService1" context="/CustomServices">
<resource methods="POST" url-mapping="/*">
<inSequence>
<log level="custom">
<property name="uri.var.servicepath" expression="get-property('To')"/>
</log>
<send>
<endpoint name="HTTPEndpoint">
<http method="POST" uri-template="http://localhost:8001/{uri.var.servicepath}"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
</api>
I hope you can help me with a similar solution for SOAP services - a way to specify a contextURI and then include the contextURI to the final endpoint that the proxy will send the request to. Note that the endpoints will be a list of entries (load balanced entries), but to keep things simple, I just kept one endpoint entry above.

I am new to WSO2 esb and so correct me if you find any mistakes.
Use case:
Check this out - http://achala11.blogspot.com/2012/08/access-wsdl-for-customuri-wso2-esb.html . It shows a way to allow custom wsdl URL for SOAP services in WSO2. Well, in my case, the services are already in place and are consumed by clients. So I couldn't use the "generated" wsdl endpoint from WSO2 and had to make sure that the existing wsdl and service URLs are going to work through WSO2. Note that I am dealing with SOAP here and there are plenty of examples for RESTful services(including REST_URL_POSTFIX to handle endpoint manipulation).
The key information you need is that there are two sequences in WSO2 that all requests go through - namely "main" and "fault" (fault is used only when there is a failure scenario).
As explained in my original question, getting the proxy service to do what I want became very challenging. Proxy service doesn't offer much in terms of propagating context to the endpoint or specifying expressions for ServiceURI variable. Then I looked at the "main" sequence entry as explained in the link I posted above. What WSO2 team is doing is just using regular expression to detect the incoming context and if it has "wsdl", they are routing the requests to a fixed wsdl endpoint and stopping the flow further. Well, I figured that we don't have to keep that code in the main sequence itself. Sequences can be chained. What that means is that you can call another sequence from main where you can do lot of magic (I didn't want to add lot of logic into the main sequence itself - my c/c++/java experiences might be stopping me from that :)) - If you are familiar with programming, sequences are like method/function calls. Main is the entry point and then you call whatever method you want inside and make further chained sequences from it etc).
First is the main sequence (filter is not needed - basically, .
<sequence name="main">
<in>
<log level="full"/>
<sequence key="ISP_seq"/>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
Now the ISP_seq where the routing of requests based on context (note the regular expressions used).
<sequence xmlns="http://ws.apache.org/ns/synapse" name="ISP_seq">
<in>
<log level="custom">
<property xmlns:ns="http://org.apache.synapse/xsd" name="Current URL" expression="get-property('To')"/>
</log>
<conditionalRouter continueAfter="false">
<conditionalRoute breakRoute="false" asynchronous="false">
<condition>
<or>
<match type="url" regex="/firstService/10\.06/.*"/>
<match type="url" regex="/firstServiceVariant/.*"/>
</or>
</condition>
<target sequence="firstService_seq"/>
</conditionalRoute>
<conditionalRoute breakRoute="false" asynchronous="false">
<condition>
<match type="url" regex="/secondService.*"/>
</condition>
<target sequence="second_seq"/>
</conditionalRoute>
</conditionalRouter>
</in>
</sequence>
Now inside the firstService_seq, you will receive all requests that has a context URI - /firstService/10.06/ (followed by anything - including ?wsdl :)) or /firstServiceVariant/ (followed by anything).
<match type="url" regex="/firstService/10\.06/.*"/>
<match type="url" regex="/firstServiceVariant/.*"/>
Ok - now to the Sequence that is going to handle the firstService and the other service.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="firstService_seq">
<in>
<!-- FIRST let us handle the WSDL requests. -->
<property name="REST_URL_POSTFIX" action="remove" scope="axis2"/>
<switch xmlns:ns="http://org.apache.synapse/xsd" source="get-property('To')">
<case regex="/firstService/10\.06/service\?[Ww][Ss][Dd][Ll]">
<send>
<endpoint>
<address uri="http://myappServer:10011/firstService10.06?wsdl" format="get"/>
</endpoint>
</send>
</case>
</switch>
<send>
<!-- below here, we will handle the actual SOAP requests -->
<endpoint>
<loadbalance algorithm="org.apache.synapse.endpoints.algorithms.RoundRobin">
<endpoint name="firstFarm_7011">
<address uri="http://hostA:7011/firstService/10.06/service"/>
</endpoint>
<endpoint name="firstFarm_7021">
<address uri="http://hostA:7021/firstService/10.06/service"/>
</endpoint>
<endpoint name="secondFarm_7011">
<address uri="http://hostX:7011/firstService/10.06/service"/>
</endpoint>
</loadbalance>
</endpoint>
</send>
</in>
<out>
<send/>
</out>
</sequence>
I am sorry for the long explanation. Somehow, I was not able to figure this out from the existing documentation. I wish the same features are available through Proxy Service as well as that is what you will think of (at least I was) when you are considering to use a ESB for the use case in my question.
Hope it helps someone. As I said earlier, correct me if I made any mistakes or if there is a better approach.

I found a cleaner/better solution - it is just an enhanced version of the above answer.
The main challenge is to get the SOAP WSDL and the Service endpoint (Context URI) work without forcing it like it happens on a proxy service approach. Note that if you can work with the contextURI WSO2 team suggests (/services//), you don't have to do any of these. The standard documentation will have all the details you need.
The logic is:
Define 3 sequences (I split them into three, but you can put all these in just one sequence as well).
main sequence (the standard built-in one - this is the sequence that gets all traffic if a request doesn't follow proxy service rules already defined in ESB). In main sequence, we just route all the incoming requests to another sequence where we do the filtering/conditinal routing.
<sequence name="main">
<in>
<log level="full"/>
<sequence key="routing_seq"/>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
*routing_sequence*
Just like in the first answer, we are going to route the incoming requests to other special sequences based on the context URI in the request.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="routing_seq">
<in>
<log level="custom">
<property xmlns:ns="http://org.apache.synapse/xsd" name="Current URL" expression="get-property('To')"/>
</log>
<conditionalRouter continueAfter="false">
<conditionalRoute breakRoute="false" asynchronous="false">
<condition>
<or>
<match type="url" regex="/firstService/10\.06/.*"/>
<match type="url" regex="/firstServiceVariant/.*"/>
</or>
</condition>
<target sequence="firstService_seq"/>
</conditionalRoute>
<conditionalRoute breakRoute="false" asynchronous="false">
<condition>
<match type="url" regex="/secondService.*"/>
</condition>
<target sequence="second_seq"/>
</conditionalRoute>
</conditionalRouter>
</in>
</sequence>
*firstservice_seq*
Now we are ready to handle the incoming request - note that we identified the application as "firstservice" in the previous step. There are two kinds of requests you can receive here - one is for WSDL and the other one is a soap request
<sequence xmlns="http://ws.apache.org/ns/synapse" name="firstService_seq">
<in>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<!-- We are checking whether the request ends with a ?wsdl or .xsd -->
<!-- For that we are using the context URI present in the 'To' field -->
<!-- if it is a wsdl or xsd request, we are converting it to a HTTP GET method -->
<!-- and sending to the final endpoint. All soap operation requests are sent as HTTP POST -->
<switch xmlns:ns="http://org.apache.synapse/xsd" source="get-property('To')">
<case regex=".*(?:\?[Ww][Ss][Dd][Ll]|\.[Xx][Ss][Dd])\s*$">
<property name="HTTP_METHOD" value="GET"/>
<property name="messageType" value="text/xml"/>
<send receive="wsdl_transformer_seq">
<endpoint key="local-enrty-firstservice-ep-key"/>
</send>
<drop/>
</case>
<!-- default means non-wsdl/non-xsd - which means a regular soap operation on the service -->
<default>
<property name="HTTP_METHOD" value="POST"/>
<send>
<endpoint key="local-enrty-firstservice-ep-key"/>
</send>
</default>
</switch>
</in>
<out>
<send/>
</out>
</sequence>
Hope you read the comments in the sequence definition. As you can see, I am converting the wsdl and xsd requests into HTTP GET to avoid any confusion at the app-tier as otherwise, there could be some junk SOAP body parts get injected from somewhere in the flow).
So basically, we check the 'To' property which contains a Context URI like /firstservice/10.06/service?WSDL (if it was a WSDL request) or /firstservice/10.06/service - if it was a SOAP request. Based on the value, we decide what to do with the request.
Note the below section in the wsdl logic:
<send receive="wsdl_transformer_seq">
<endpoint key="local-enrty-firstservice-ep-key"/>
</send>
<drop/>
</send>
What happens is that when we pull the wsdl from the endpoint (which I will explain shortly), schemaLocation and soap:address fields contain the information (hostname and port) of actual server instance that processed the request. This is an unwanted result as you are exposing your internal details to the clients and others. So we should mask it. The way to do that is to use a special feature in WSO2. In a send, you can specify another sequence that will receive the results of the send before it goes to the client. It is more or less like you define an <out> portion in a sequence. Since we don't want this particular manipulation happen to all requests, we are not defining a special sequence that gets applied to only wsdl/xsd reqeusts. In the wsdl_transformer_seq, we use XSLT to change the hostname and port present in the wsdl or xsd response.
wsdl_transformer_seq
<sequence name="wsdl_transformer_seq">
<xslt xmlns:ns="http://org.apache.synapse/xsd"
key="xslt-url-manipulator"
source="/"/>
<send/>
</sequence>
Note that I externalized these entries (xslt transformer for example) and get them loaded through a local-entry registry.
<localEntry key="xslt-url-manipulator"
src="file:repository/myapp/resources/transform/url-in-wsdl-transform.xslt"/>
Now the contents of url-in-wsdl-transform.xslt
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="newURL">https://services.mycompany.com</xsl:param>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soap:address/#location">
<xsl:attribute name="location">
<xsl:value-of select="replace(.,'https?://[^/]*',$newURL)"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="xs:import/#schemaLocation">
<xsl:attribute name="schemaLocation">
<xsl:value-of select="replace(.,'https?://[^/]*',$newURL)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Note the name - https://services.mycompany.com - in the xslt above. You can change it to whatever you want and the schemaLocation and soap:address fields in the wsdl and xsd will now use that in the host:port area
And finally the endpoint local-enrty-firstservice-ep-key
Note that this as well is an externally loaded file - just like the xslt entry above. So I will only post the content of the actul external file.
This was a tough cookie and I had to dig through WSO2 source code and figure out some "undocumented" features. Well, it is "undocumented" in WSO2 world, but documented otherwise as WSO2 uses a third-party library which has many features that are not published in WSO2.
Note that the endpoint points to the app-tier instances and we use the roundrobin algorithm to distribute the traffic to the avilalble app-tier instances.
<endpoint xmlns="http://ws.apache.org/ns/synapse">
<loadbalance algorithm="org.apache.synapse.endpoints.algorithms.RoundRobin">
<endpoint name="firsthost_5012">
<http uri-template="http://firsthost.com:5012{+uri.var.servicepath}"/>
</endpoint>
<endpoint name="firsthost_5022">
<http uri-template="http://firsthost.com:5022{+uri.var.servicepath}"/>
</endpoint>
</loadbalance>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="uri.var.servicepath"
expression="get-property('To')"/>
</endpoint>
There is lot of magic happens here -
First we save the context uri to a special variable called uri.var.servicepath
Now we will use that with the new "http endpoint" feature available from WSO 4.7.0 onwards.
http endpoint uses uri-template - where you can dynamically construct the endpoint. So I don't have to specify the context URI in the configuration -
So let us say the original request we got into ESB was like this:
http://esbhost.com:8280/firstservice/10.06/service
The context uri here is "/firstservice/10.06/service" - so we want this to be appended to the actual app-tier server url. In other words, I want it to become http://firsthost.com:5022/firstservice/10.06/service
In http endpoint, it allows us to use the special variable - uri.var.servicepath that we defined earlier.
<http uri-template="http://firsthost.com:5022{+uri.var.servicepath}"/>
since uri.var.servicepath already contains a '/' at the beginning, I am not specifying separately. But note the + sign in the brackets. What is that for? hmmm - well, it turned out that WSO2 uses the interesting third-party library - "damn good uri processor" - it is mainly used for RESTful APIs. Unfortunately, if you plainly use the field like this, http://firsthost.com:5022{uri.var.servicepath}, the 3rd party library will convert the special characters present in the context uri to their http safe equivalent - something like %20f or whatever. So our url now becomes http ://firsthost:5022%20ffirstservice%20f10.06.... - it is not good. Well here comes the special feature in the 3rd party library that saves the day. If you put a + at the beginning of the special variable, this translation is turned off ;) - voila - we got what we wanted.
So that is it folks. I will try to post the full configuration below (minus the externalized entries that you can find in the above sections)
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<localEntry key="xslt-url-manipulator"
src="file:repository/myapp/resources/transform/url-in-wsdl-transform.xslt"/>
<localEntry key="local-enrty-firstservice-ep-key"
src="file:repository/myapp/resources/endpoint/firstservice-endpoints.xml">
</localEntry>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="routing_seq">
<in>
<log level="custom">
<property xmlns:ns="http://org.apache.synapse/xsd" name="context URI" expression="get-property('To')"/>
</log>
<conditionalRouter continueAfter="false">
<conditionalRoute breakRoute="false" asynchronous="false">
<condition>
<or>
<match type="url" regex="/firstService/10\.06/.*"/>
<match type="url" regex="/firstServiceVariant/.*"/>
</or>
</condition>
<target sequence="firstService_seq"/>
</conditionalRoute>
<conditionalRoute breakRoute="false" asynchronous="false">
<condition>
<match type="url" regex="/secondService.*"/>
</condition>
<target sequence="second_seq"/>
</conditionalRoute>
</conditionalRouter>
</in>
</sequence>
<sequence name="wsdl_transformer_seq">
<xslt xmlns:ns="http://org.apache.synapse/xsd"
key="xslt-url-manipulator"
source="/"/>
<send/>
</sequence>
<sequence name="fault">
<log level="full">
<property name="MESSAGE" value="Executing default 'fault' sequence"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
</log>
<drop/>
</sequence>
<sequence name="firstservice_seq">
<in>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<switch xmlns:ns="http://org.apache.synapse/xsd" source="get-property('To')">
<case regex=".*(?:\?[Ww][Ss][Dd][Ll]|\.[Xx][Ss][Dd])\s*$">
<property name="HTTP_METHOD" value="GET"/>
<property name="messageType" value="text/xml"/>
<send receive="wsdl_transformer_seq">
<endpoint key="local-enrty-firstservice-ep-key"/>
</send>
<drop/>
</case>
<default>
<property name="HTTP_METHOD" value="POST"/>
<send>
<endpoint key="local-enrty-firstservice-ep-key"/>
</send>
</default>
</switch>
</in>
</sequence>
<sequence name="main">
<in>
<filter xmlns:ns="http://org.apache.synapse/xsd"
source="get-property('To')"
regex="http://localhost:9000.*">
<then>
<send/>
</then>
<else/>
</filter>
<sequence key="routing_seq"/>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
</definitions>
I know it is a very lengthy post - but wanted to explain the details for those who care.
Hope it helps someone.

Related

WSO2 API Manager - load balancing with dynamic endpoints

I've got an API that uses dynamic endpoints. Now I want it to also do load balancing. I know how to do that using element, however when using dynamic endpoints in APIM you only manipulate the "To" header.
Below is the mediation sequence used to set the endpoint. Instead of addressing just a single endpoint in each case, I'd like to be able to loadbalance between 2 servers.
Any thoughts?
Thanks.
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="inSequence_clientEquipmentsAPI_1_2_STG" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<!-- check for healthcheck operation -->
<filter xpath="get-property('To')='/etc/equipments/client/1.0/healthCheck'">
<!-- if healthCheck, directs to healthCheck API (EI)-->
<then>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<header name="To" value="http://10.220.160.36:8290/healthCheck/clientEquipments"/>
</then>
<!-- else direct to regular clientEquipment API (EI)-->
<else>
<property name="newContext" expression="substring-after(get-property('To'),'/etc')"/>
<header name="To" expression="fn:concat('http://10.220.160.36:8290', $ctx:newContext)"/>
</else>
</filter>
</sequence>

WSO2 API Manager 1.9 - Append fixed header information

I need to append a fixed Authorization header to an API endpoint. This is an application specific token for my endpoint system so I do not need API subscribers to enter this information nor want them in the know.
An almost similar question was raised before but hasn't been answered.
The documentation here doesn't provide specific details and is a bit obscure so I am lost on how to achieve this. Has anybody done this?
Appreciate any help, cheers!
Do you want to set this as a custom HTTP header and send it to the backend? If yes, then you can use a property mediator to set this as a transport scope property just before the send mediator inside inSequence of your API, as shown below. Have a look at the property Fixed-Authorization set just before the send mediator.
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse"
name="admin--Hello"
context="/hello"
version="1.0.0"
version-type="url">
<resource methods="POST GET OPTIONS DELETE PUT"
url-mapping="/*"
faultSequence="fault">
<inSequence>
<filter source="$ctx:AM_KEY_TYPE" regex="PRODUCTION">
<then>
<property name="Fixed-Authorization" value="yourAppToken" scope="transport"/>
<send>
<endpoint name="admin--Hello_APIproductionEndpoint_0">
<http uri-template="http://echo.jsontest.com/key/value/one/two"/>
</endpoint>
</send>
</then>
<else>
<sequence key="_sandbox_key_error_"/>
</else>
</filter>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
<handlers>
<handler class="org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler"/>
<handler class="org.wso2.carbon.apimgt.gateway.handlers.throttling.APIThrottleHandler">
<property name="id" value="A"/>
<property name="policyKey" value="gov:/apimgt/applicationdata/tiers.xml"/>
</handler>
<handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageHandler"/>
<handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtGoogleAnalyticsTrackingHandler">
<property name="configKey" value="gov:/apimgt/statistics/ga-config.xml"/>
</handler>
<handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerExtensionHandler"/>
</handlers>
</api>
If you access the API, this property will be sent as a HTTP header to your backend endpoint. You can refer this post for more detailed explanation.
If you just want to pass this application token to the backend (but not as HTTP header), then you can pass it to the backend using JWT. Refer this document for more details.

Posting plain text to ActiveMQ from WSO2 proxy

I am new to the WSO2 and ActiveMQ, and I have been trying to achieve a seemingly simple message transformation, but without success.
I need to expose a web service on WSO2 which will take the value of only one particular input argument (out of three),
and forward that value as a plain text string on to the ActiveMQ queue. So, there is no backend service, no response to process,
only a simple one-way forwarding operation is required with value extraction and a transformation to plain text before posting to the queue.
I've been through the proxy samples and a lot of google-ing, yet, the most I have managed is to get that required value on the queue,
but as a POX, and that is not satisfactory.
Actually I have doubts whether WSO2 is capable of posting a plain text string at all,
and yet, there are articles where people swore that it can do almost anything imaginable, only they do not explain exactly how.
What I do is that I extract the required value "arg2" using the PayloadFactory mediator,
into an <xdr> element (because the PayloadFactory insists on either the XML or the JSON format, no plain text allowed).
Then I send that element to the queue. Question #1 is whether WSO2 can somehow convert that xml into plain text automatically?
Currently I think not.
So, before sending, I have tried many things to get that value out without any xml tags,
mostly using the Enrich mediator and even Javascript, but at one point or another, the thing would fail - either the WSO2 wouldn't let me define such mediation,
or it would simply not perform as expected/required, or fail at runtime.
The Enrich mediator is also not really clearly explained - what does "source" mean,
and what is the "target", with all those options - whatever options I chose, I've neever seen any change done to my message by the Enrich mediator.
What am I doing wrong, please? :)
Below is my current WSO2 proxy definition, which now contains pretty much everything I've compiled from the net so far,
but it still only posts the value format to the queue - so this is merely an illustration of what I've tried so far:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="VomsXdrPlain"
transports="http"
statistics="disable"
trace="enable"
startOnLoad="true">
<target>
<inSequence>
<!-- first, the extraction -->
<payloadFactory media-type="xml">
<format>
<xdr xmlns="">$1</xdr>
</format>
<args>
<arg xmlns:xsd="http://api.service.com/"
evaluator="xml"
expression="//xsd:arg2"/>
</args>
</payloadFactory>
<!-- the following was added out of desperation -->
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="FORCE_POST_PUT_NOBODY"
value="true"
scope="axis2"
type="BOOLEAN"/>
<!-- here the idea was to put the value into a property, so it might be used in the Enrich mediator -->
<property name="xdrTicket"
expression="//xdr/text()"
scope="default"
type="STRING"/>
<!-- how to use the Enrich mediator properly for this purpose? -->
<enrich>
<source type="property" clone="true" property="xdrTicket"/>
<target type="body"/>
</enrich>
<!-- then I tried scripting... but the setPayLoadXML method also insists on tags so I've put "abc" -->
<script language="js">
var xmlPayload = mc.getPayloadXML();
var xdrTick = xmlPayload.substr(0,36);
mc.setPayloadXML(<abc>{xdrTick}</abc> );
</script>
<!-- this is posting to the queue and it works, but again, allowed formats are only POX, SOAP, REST, or AS-IS... but no PLAIN TEXT -->
<send>
<endpoint>
<address uri="jms:/VomsXdrService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue"
format="pox"/>
</endpoint>
</send>
</inSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules xmlns="">
<jmsProperty>contentType</jmsProperty>
<default>text/plain; charset=ISO-8859-1</default>
</rules>
</parameter>
<parameter name="ContentType" value="text/plain"/>
<parameter name="transports">jms</parameter>
<description/>
</proxy>
The request is like the following:
<body>
<p:writeXDRRequest xmlns:p="http://api.service.com/">
<xsd:arg0 xmlns:xsd="http://api.service.com/">VOMS</xsd:arg0>
<xsd:arg1 xmlns:xsd="http://api.service.com/">SDR</xsd:arg1>
<xsd:arg2 xmlns:xsd="http://api.service.com/">1.0|321|2014-09-24T13:25:19.183+0000</xsd:arg2>
</p:writeXDRRequest>
</body>
On the queue, only the value of arg2 is expected, in plain text, without any tags:
1.0|321|2014-09-24T13:25:19.183+0000
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="VomsXdrPlain"
transports="http"
statistics="disable"
trace="enable"
startOnLoad="true">
<target>
<inSequence>
<payloadFactory media-type="xml">
<format>
<text xmlns="http://ws.apache.org/commons/ns/payload">$1</text>
</format>
<args>
<arg xmlns:xsd="http://api.service.com/"
evaluator="xml"
expression="//xsd:arg2"/>
</args>
</payloadFactory>
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="messageType" value="text/plain; charset=windows-1252" scope="axis2"/>
<!-- this is posting to the queue and it works, but again, allowed formats are only POX, SOAP, REST, or AS-IS... but no PLAIN TEXT -->
<send>
<endpoint>
<address uri="jms:/dynamicQueues/TestQueue?transport.jms.ConnectionFactory=myQueueConnectionFactory"/>
</endpoint>
</send>
</inSequence>
</target>
<description/>
</proxy>
see https://docs.wso2.com/display/ESB481/Converting+the+SOAP+Messages+to+Plain+Text+Mail

WSO2: Address Endpoint seems to overwrite wsa:To WS-Addressing property

Forwarding a SOAP message from WSO2ESB via another ESB to a backend web-service does not seem possible, because the original wsa:To value is modified to the URL of the intermediate ESB.
The following configuration shows this behavior:
<header name="To" value="http://ws.backend.com/service"/>
<property name="PRESERVE_WS_ADDRESSING" value="true"/>
<send>
<endpoint name="IntermediateESB">
<address uri="http://esb.intermediate.com/proxy">
<enableAddressing/>
</address>
</endpoint>
</send>
The SOAP header now contains the following wsa:To:
<wsa:To>http://esb.intermediate.com/proxy</wsa:To>
The address uri seems to overwrite the original wsa:To value.
This will fail in the intermediate ESB, because it expects the URL of the backend web-service in wsa:To.
The SOAP header should have contained the following for the intermediate ESB to work properly:
<wsa:To>http://ws.backend.com/service</wsa:To>
What configuration is possible to fix this?
You need to provide your backend address in wsa:ReplyTo header tag. So your intermediate will proceed the response to backend service.
<header name="ReplyTo" value="http://ws.backend.com/service"/>
More info : http://www.w3.org/Submission/ws-addressing/
The solution is that you have to build the WS-Addressing headers yourself explicitly, and not use <enableAddressing/>!
Example:
<header xmlns:wsa="http://www.w3.org/2005/08/addressing" name="wsa:To" value="http://ws.backend.com/service"/>
<header xmlns:wsa="http://www.w3.org/2005/08/addressing" name="wsa:MessageID" expression="get-property('MessageID')"/>
<header xmlns:wsa="http://www.w3.org/2005/08/addressing" name="wsa:Action" value="http://ws.backend.com/operation"/>
<header name="To" value="http://esb.intermediate.com/proxy"/>
<header name="Action" value="http://ws.backend.com/operation"/>
<property name="PRESERVE_WS_ADDRESSING" value="true" scope="default" type="STRING"/>
<send>
<endpoint name="IntermediateESB">
<address uri="http://esb.intermediate.com/proxy"/>
</endpoint>
</send>
Note that you have to set 'Action' twice with the same value.
Also note that you can use 'To' with a different value, and use a 'default' endpoint instead of the 'address' endpoint above.
The SOAP message is posted to 'http://esb.intermediate.com/proxy', and the WS-Addressing headers are:
<wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://ws.backend.com/service</wsa:To>
<wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:uuid:52aad1f4-9295-43f6-90c0-304e87922c27</wsa:MessageID>
<wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://ws.backend.com/operation</wsa:Action>
The 'IntermediateESB' can now forward this SOAP message to 'http://ws.backend.com/service'.

Error while validating GET request paramater in WSO2 ESB 4.0.3

I am trying to validate GET request parameter in proxy service in WSO2 ESB 4.0.3. I have following code logic
<filter source="get-property('To')" regex="^(?=.*inSerialNr=).*$">
<then>
<send>
<endpoint key="conf:/tqs/rma/ds_endpoint.xml" />
</send>
</then>
<else>
<log level="custom" separator=",">
<property name="Missing-Input" value="Input validation failed...Missing Input Parameter - inSerialNr" />
</log>
<script language="js"><![CDATA[mc.setPayloadXML(<ERROR><DESCRIPTION>Input validation failed...Missing Input Parameter - inSerialNr</DESCRIPTION></ERROR>);]]></script>
<property name="RESPONSE" value="true" scope="default" type="STRING" />
<send>
<endpoint key="conf:/tqs/tqsAnonymous.xml" />
</send>
<drop />
</else>
</filter>
I am expecting the message processing to be dropped when the parameter "inSerialNr" is missing. How ever it can not find the "http://www.w3.org/2005/08/addressing/anonymous" end point which is the client.
Even I tried doing the xslt to make the result as text/plain and send it back but still it can not find the send to anonymous end point. Since it can not find the end point it goes to outsequence and executes the code there.
How the error handling for the get parameter is done?
Please advice.
thanks
Abhijit
please have a look at here[1]. This shows how to send an response message from the in sequence.
[1] http://wso2.org/library/knowledge-base/generating-simple-response-using-wso2-enterprise-service-bus