Regd. Conditional Router in wso2 esb - wso2

I am working on conditional router in wso2 esb and my scenario is as follows.
I extracted studentno in payload and wanted to perform conditional router on the top of that but this is working for header and query params and not for query variables or a value extracted from payload. I tried for the solution but I got switch-case as a solution. Is this is a limitation in conditional router that works only with header and params? If no please provide your inputs on the condition in conditional router.
Thanks in advance.

There are two types to achieve your requirement. You should be able to use either the type soap [2] or the type property [1] to route based on the payload content. Refer to the sample below. The other available types can be found in the documentation [3].
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="conditionalRouter"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<property expression="$body//symbol" name="requestProperty"/>
<log level="custom">
<property expression="$body//symbol" name="requestProperty"/>
</log>
<conditionalRouter continueAfter="false">
<conditionalRoute breakRoute="false">
<condition>
<match regex="WSO2.*" source="//symbol" type="soap"/>
</condition>
<target sequence="cnd1_seq"/>
</conditionalRoute>
<conditionalRoute breakRoute="false">
<condition>
<match regex="IBM.*" source="requestProperty" type="property"/>
</condition>
<target sequence="cnd2_seq"/>
</conditionalRoute>
</conditionalRouter>
</inSequence>
</target>
<description/>
</proxy>
request 1
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<request>
<symbol>WSO2</symbol>
</request>
</soapenv:Body>
</soapenv:Envelope>
request 2
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<request>
<symbol>WSO2</symbol>
</request>
</soapenv:Body>
</soapenv:Envelope>
Note
The Conditional Router Mediator is removed from the EI 6.5.0 version onwards [4]. Therefore if you have already developed your mediation using the switch case mediator, better to use the same since it would be easier for you if you decide to migrate to a new EI version.
[1]-https://github.com/wso2/wso2-synapse/blob/v2.1.7-wso2v111/modules/commons/src/main/java/org/apache/synapse/commons/evaluators/config/TextProcessingEvaluatorFactory.java#L60
[2]-https://github.com/wso2/wso2-synapse/blob/v2.1.7-wso2v111/modules/commons/src/main/java/org/apache/synapse/commons/evaluators/config/TextProcessingEvaluatorFactory.java#L66
[3]-https://docs.wso2.com/display/EI620/Sample+157%3A+Conditional+Router+for+Routing+Messages+based+on+HTTP+URL%2C+HTTP+Headers+and+Query+Parameters
[4]-https://docs.wso2.com/display/EI650/About+this+Release

Related

How to use enrich mediator to set SOAP envelope to the XML body using WSO2 ESB

I need to set soap envelope to the xml body using enrich mediator.
I created XML body inside the payload factory mediator. I get that body to property value.
property
<property expression="$body/*[1]" name="INPUT_MESSAGE" scope="default" type="OM" xmlns:ns="http://org.apache.synapse/xsd"/>
Body is like this
<bas:setMOAttributes xmlns:bas="http://www.3gpp.org/ftp/Specs/archive/32_series/32607/schema/32607-700/BasicCMIRPData">
<queryXpathExp>
<soap:baseObjectInstance xmlns:soap="http: //Here is only few lines
Now I need to add soap envelop.I used enrich mediator after INPUT_MESSAGE property
<enrich>
<source clone="true" type="inline">
<soapenv:Envelope xmlns:bas="http://www.3gpp.org/ftp/Specs/archive/32_series/32607/schema/32607-700/BasicCMIRPData" xmlns:soap="http://www.alcatel-lucent.com/soap_cm" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<list xmlns=""/>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<enrich>
<source clone="true" property="INPUT_MESSAGE" type="property"/>
<target type="body"/>
</enrich>
But I couldn't get xml body with soap envelop. What is the way to do this
Try this it will work
Request with body like this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">
<soapenv:Header/>
<soapenv:Body>
<bas:setMOAttributes xmlns:bas="http://www.3gpp.org/ftp/Specs/archive/32_series/32607/schema/32607-700/BasicCMIRPData">
<queryXpathExp>
<soap:baseObjectInstance xmlns:soap="http://www.alcatel-lucent.com/soap_cm">
hello
</soap:baseObjectInstance>
</queryXpathExp>
</bas:setMOAttributes>
</soapenv:Body>
</soapenv:Envelope>
Proxy with Enrich mediator like this
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="test2"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<property expression="$body/*[1]"
name="INPUT_MESSAGE"
scope="default"
type="STRING"/>
<enrich>
<source clone="true" type="inline">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<list xmlns=""/>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<enrich>
<source clone="true" property="INPUT_MESSAGE" type="property"/>
<target type="body"/>
</enrich>
<respond/>
</inSequence>
</target>
<description/>
</proxy>
Output like this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<list><![CDATA[<bas:setMOAttributes xmlns:bas="http://www.3gpp.org/ftp/Specs/archive/32_series/32607/schema/32607-700/BasicCMIRPData">
<queryXpathExp>
<soap:baseObjectInstance xmlns:soap="http://www.alcatel-lucent.com/soap_cm">
hello
</soap:baseObjectInstance>
</queryXpathExp>
</bas:setMOAttributes>]]></list>
</soapenv:Body>
</soapenv:Envelope>
What about using payload factory for this ?
<payloadFactory description="Add Soap Envelop" media-type="xml">
<format>
<soapenv:Envelope xmlns:bas="http://www.3gpp.org/ftp/Specs/archive/32_series/32607/schema/32607-700/BasicCMIRPData" xmlns:soap="http://www.alcatel-lucent.com/soap_cm" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
$1
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('INPUT_MESSAGE')"/>
</args>
</payloadFactory>
Look at example 5 here in payload factory documentation
Using payload factory will give you a clean solution. If you want to use enrich mediator to set the envelope, you need to save it in a property first and then use property in enrich mediator. Same as you have done for saving the body in a property first and then using it in a enrich mediator.
Hope that helps.

WSO2 ESB Send attachment with Soap

Tested soap with attachment Axis 2 server sample soapWithAttachment service using soap UI client; any attachments formats jpeg, png, xml can be uploaded successfully through soap UI. Below is the input soap xml used to post in Soap UI and attached the attachment to the soap UI and post it. How this can be achieved through WSO2 ESB?
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="http://service.soapwithattachments.sample">
<soap:Header/>
<soap:Body>
<ser:uploadFile>
<!--Optional:-->
<ser:name>new2</ser:name>
<!--Optional:-->
<ser:attchmentID>new13.xml</ser:attchmentID>
</ser:uploadFile>
</soap:Body>
</soap:Envelope>
As per my analysis client needs to process the file using data handler and generate the Attachment ID, this would be inbuilt for Soap UI; I would like to know how this can be achieved through WSO2 ESB without using custom Java mediator. I am using WSO2 version 4.9.0. I have created the WSO2 ESB proxy as shown below.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="attachmentProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target faultSequence="fault">
<inSequence>
<send>
<endpoint>
<address uri="http://localhost:8080/axis2/services/soapWithAttachment"
optimize="mtom"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL uri="http://localhost:8080/axis2/services/soapWithAttachment?wsdl"/>
</proxy>

WSO2 XSLT Mediator not resolving xpath

hopefully someone can point out the blindingly obvious to me - I want to perform a few simple translations on a soap payload before I send to a backend service - crucially, I need access to all the soap-headers delivered in the original payload.
My naive(?) thinking was to simply set the source attribute for the <xslt> mediator to "/" as Im aware by default it will start from the first child of the <body>, and I really need access to the headers.
WSO2 returns a "The evaluation of the XPath expression / did not result in an OMNode" error.
Are there one or more WSO2/xpath interworking quirks that Ive missed in the literature? Any pointers gratefully recieved, thanks
As Tishan mentioned you can use $header synapse xpath variable to access soap headers in message context. But it's bit tricky when it comes to xslt mediator. You cannot directly access message context values inside xslt stylesheet. But it is possible to pass these values as parameters and use in transformation. Let's see how we can achieve this.
Below is how account.xslt file looks like. Please note that there are two parameters called PARAM_SSN and PARAM_ACCT_NO used to assign value for <ssn></ssn> and <accountNumber></accountNumber>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="PARAM_SSN"></xsl:param>
<xsl:param name="PARAM_ACCT_NO"></xsl:param>
<xsl:template match="/">
<account xmlns="http://services.samples">
<ssn>
<xsl:value-of select="$PARAM_SSN"></xsl:value-of>
</ssn>
<accountNumber>
<xsl:value-of select="$PARAM_ACCT_NO"></xsl:value-of>
</accountNumber>
<accountHolder>
<xsl:value-of select="//name"></xsl:value-of>
</accountHolder>
</account>
</xsl:template>
</xsl:stylesheet>
Above file saved in registry of WSO2 ESB under /_system/governance/transform/account.xslt
Next is sample proxy which do the transformation with account.xslt
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TransformExample"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<xslt key="gov:/transform/account.xslt">
<property name="PARAM_SSN" expression="$header/seccode"/>
<property name="PARAM_ACCT_NO" expression="$trp:acctNo"/>
</xslt>
<log level="custom">
<property name="Transformed Payload" expression="$body"/>
</log>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description/>
</proxy>
Here you could see that inside <xslt> mediator, I am passing values for two parameters define in xslt by accessing message context. Value for PARAM_SSN taken from soap header and value for PARAM_ACCT_NO taken from transport header. This proxy service called by soapUI with below payload.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<seccode>987654321</seccode>
</soapenv:Header>
<soapenv:Body>
<request>
<name>Indika Sampath</name>
</request>
</soapenv:Body>
</soapenv:Envelope>
Also I am sending acctNo as transport header along with request. Once this hit the proxy, you could see transformed output log as below in console.
[2016-01-09 07:19:02,146] INFO - LogMediator Transformed Payload = <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<account xmlns="http://services.samples"><ssn>987654321</ssn><accountNumber>123456789</accountNumber><accountHolder>Indika Sampath</accountHolder></account>
</soapenv:Body>
Hope this would resolve your problem.
Cheers!
You can access SOAP headers using Synapse Xpath Variable $header in your source xpath (Ex:$header/wsa:To). Hope this helps!!

WSO2 ESB - WSAddressing Set To Header

I am trying to get WSO2 to work with WCF - WCF expects the WSAddressing headers to be set and correct. I am trying to use a Header Mediator with my WSDL Proxy Service and to set the To Header but it never seems to do anything - I always get the error message from WCF: "The message with To '' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree."
Here is my proxy setup - what do I need to do to get this working?
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="PingService"
transports="http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<header xmlns:a="http://www.w3.org/2005/08/addressing"
name="a:To"
scope="default"
value="http://localhost/PingService/PingService.svc"/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<endpoint>
<wsdl service="PingService"
port="AccountService_WsHttp"
uri="http://uk-dev-10706.wintech.local/PingService/PingService.svc?singleWsdl"/>
</endpoint>
</target>
<description/>
</proxy>
I think you can enable "WS-Addressing" for your endpoint.
http://docs.wso2.org/display/ESB480/WSDL+Endpoint
Please try with transport scope may be that will work in your case.
<header xmlns:a="http://www.w3.org/2005/08/addressing"
name="a:To"
scope="transport"
value="http://localhost/PingService/PingService.svc"/>

Service Mediation Using Proxy Services -WSO2

I'm new to this area and i need to access my web service via the ESB. as it mentioned in here - Service Mediation Using Proxy Services i tried to to create it. after that i run it and get the response as follows :
<TryitProxyError xmlns:h="http://wso2.org/ns/TryitProxy"
h:status="SOAP envelope error">org.apache.axis2.AxisFault:
The input stream for an incoming message is null.</TryitProxyError>
but i tried to run same web method using SOAPUi and get the expected out put as below:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<getPatientHistoryResponse xmlns="http://tilani.lk/">
<getPatientHistoryResult>
<NIC>123</NIC>
<FullName>ABC DEF</FullName>
<FirstName>ABC</FirstName>
<Surname>DEF</Surname>
<Title>Mr.</Title>
<Gender>M/Gender>
</getPatientHistoryResult>
</getPatientHistoryResponse>
</soap:Body>
</soap:Envelope>
what is the reason for this? i created this using .net
my WSDL Address - http://localhost:2935/PatientRegService.asmx?WSDL
then in
Define Endpoint as - http://localhost:2935/PatientRegService.asmx
EDIT
my proxy configuration is as follows:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="PatientManagement" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="http://localhost:2935/PatientRegService.asmx?WSDL"/>
</endpoint>
</target>
<publishWSDL uri="http://localhost:2935/PatientRegService.asmx?WSDL"/>
<description></description>
</proxy>
If you just want to access your web service via ESB you need to create a proxy service and access the proxy service URI instead of the original service URI. Just follow the Pass Through Proxy example.
Try the following proxy and see waht you are getting. Add this proxy configuration via source view editor.
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="testProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<log level="full">
<property name="testprop" value="incoming message"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:2935/PatientRegService.asmx"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
</proxy>