Switching OutSequence in WSO2 ESB Proxy Service based oh SOAP response - proxy

I deployed a proxy service in WSO2 ESB for dataset retrieving from a SOAP WS, and i have an OutSequence based on a sequence calling a template.
I have to channel various WS response based on the different request routing them on different files written by the vfs transport.
Actual sequence is the following:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="seq_prova_con_template">
<call-template target="file">
<with-param name="filename" value="IstatAllDataflow-template.xml"></with-param>
</call-template>
</sequence>
I think about a switch-case mediator but i'd like to understand how "catch" the information for choosing the right case. In the example:
`<switch source="//m0:getQuote/m0:request/m0:symbol" xmlns:m0="http://services.samples/xsd">
<case regex="IBM">
<!-- the property mediator sets a local property on the *current* message -->
<property name="symbol" value="Great stock - IBM"/>
</case>
<case regex="MSFT">
<property name="symbol" value="Are you sure? - MSFT"/>
</case>
<default>
<!-- it is possible to assign the result of an XPath or JSON Path expression as well -->
<property name="symbol"
expression="fn:concat('Normal Stock - ', //m0:getQuote/m0:request/m0:symbol)"
xmlns:m0="http://services.samples/xsd"/>
</default>
`
i ask myself how to set the source param of the switch case, and i'd like to know if someone has already implemented a solution like this in order to use a single proxy service for differentiate various answer from the WS.
My sequence is the following:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="seq_template_switch">
<switch xmlns:ns="http://org.apache.synapse/xsd" xmlns:m0="http://services.samples" source="??????">
<case regex="QueryStructure">
<call-template target="file">
<with-param name="filename" value="IstatAllDataflow-template.xml"></with-param>
</call-template>
</case>
<case regex="GetCompactData">
<call-template target="file">
<with-param name="filename" value="GetCompactData-template.xml"></with-param>
</call-template>
</case>
</switch>
</sequence>
I need to catch the choice for the switch case from che method inside the request of my request message, in order to write a certain file when i ask for a kind of answer, and another file with a different name when i ask for another kind of answer.
[EDIT] Log file has this:
TID: [0] [ESB] [2015-09-18 10:33:09,125] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:7cc540d3-2893-4b0e-8a24-ab4538236d45, Direction: response, Envelope: <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><QueryStructureResponse xmlns="http://ec.europa.eu/eurostat/sri/service/2.0"><QueryStructureResult><RegistryInterface xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message"><Header><ID>IT1001</ID><Test>true</Test><Name xml:lang="en">ISTAT_JD_237</Name><Prepared>2001-03-11T15:30:47+01:00</Prepared><Sender id="ISTAT"><Name xml:lang="en">Italian Statistical Institute</Name><Contact>
It would be useful making the choice of switch/case mediator about the tag <QueryStructureResponse>. Instead of this tag i could have<GetCompactData> , for example. I'd like to create a switch/case mediator that is driven by the presence of one of this two tags. This would be a good beginning for understanding how to use XPath location and using a single sequence for differentiating SOAP answers in different file by vfs transport.The choice of the file to write in would be taken by the kind of answer from the WS.

Below should work for you. It is checking if QueryStructureResponse exists in SOAP xml or not. If available then it will call IstatAllDataflow-template.xml template otherwise it will invoke GetCompactData-template.xml template.
<switch source="boolean($body//*[local-name() = 'QueryStructureResponse'])">
<case regex="true">
<call-template target="file">
<with-param name="filename" value="IstatAllDataflow-template.xml"></with-param>
</call-template>
</case>
<case regex="false">
<call-template target="file">
<with-param name="filename" value="GetCompactData-template.xml"></with-param>
</call-template>
</case>
</switch>
Another solution using filter in WSO2 esb.
<filter source="boolean($body//*[local-name() = 'QueryStructureResponse'])" regex="true">
<then>
<log>
<property name="======================== TRUE =========================" value="true"/>
</log>
<call-template target="file">
<with-param name="filename" value="IstatAllDataflow-template.xml"/>
</call-template>
</then>
<else>
<log>
<property name="==================== FALSE =========================" value="false"/>
</log>
<call-template target="file">
<with-param name="filename" value="GetCompactData-template.xml"/>
</call-template>
</else>
</filter>

Related

how i can add values to my Adress endpoint in wso2 ESB/EI

i want to add values dynamically to adress endpoint in the proxy in wso2 ESB/EI
<address uri="mqtt:/SampleProxy?mqtt.server.host.name=thingsboard.cloud&mqtt.server.port=1883&mqtt.client.id=esb.test.sender&mqtt.topic.name=v1/devices/me/telemetry&mqtt.subscription.qos=0&mqtt.blocking.sender=true&mqtt.subscription.username=25416990;">
lets say for exemple i want to add "test" at the end of the endpoint how i can do this ?
For a similar problem, but with sending msg to rabbitmq, I created template, where i set exchangeName and routingKey dynamicaly. In the same manner, you can create your own template. You need to create Header named "To" and using XPATH concate interesting address endpoint, and for dynamic values you just use $func:{parameter name}
Something like below:
<?xml version="1.0" encoding="UTF-8"?>
<template xmlns="http://ws.apache.org/ns/synapse" name="rabbitmq.sender">
<parameter name="exchangeName"/>
<parameter name="routingKey"/>
<sequence>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<header name="To"
scope="default"
expression="concat('rabbitmq:/?rabbitmq.connection.factory=CachedRabbitMQConnectionFactory&rabbitmq.exchange.name=',$func:exchangeName,'&rabbitmq.queue.routing.key=',$func:routingKey)"/>
<send/>
</sequence>
</template>
To use that, call-template mediator is needed. In brackets you can put expression, like below:
<call-template target="send.rabbitmq">
<with-param name="exchangeName" value="test"/>
<with-param name="routingKey" value="{get-property('testValue')}"/>
</call-template>

Search a user in multiple systems through WSO2 ESB proxy

I need to send just one request (can be a proxy url) which takes user id as input and call multiple endpoints and return the response after aggregating all of them.
Currently I am using a proxy service implementation to achieve it but is returns just one response(can be from any of the endpoints) and not able to combine responses from other systems/endpoints. Though I can see the response from another endpoint in my server console.
Below is the code I implemented so far:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="ProxyTestTwoW"
transports="http,https"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log/>
<clone>
<target>
<sequence>
<property name="Application" value="Application1"/>
<property name="messageType"
value="application/xacml+json"
scope="axis2"
type="STRING"/>
<property name="Authorization"
expression="fn:concat('Basic ', base64Encode('username:password'))"
scope="transport"/>
<send>
<endpoint>
<address uri="localhost:8080/iiq/rest/identities/9000070"/>
</endpoint>
</send>
</sequence>
</target>
<target>
<sequence>
<property name="Application" value="Application2"/>
<property name="messageType"
value="application/xacml+json"
scope="axis2"
type="STRING"/>
<property name="Authorization"
expression="fn:concat('Basic ', base64Encode('username:password'))"
scope="transport"/>
<send>
<endpoint>
<address uri="http://localhost:8080/iiq/rest/identities/9000071"/>
</endpoint>
</send>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<log level="full" description="">
<property name="Component" expression="get-property('Application')"/>
</log>
<aggregate>
<completeCondition>
<messageCount min="2"/>
</completeCondition>
<onComplete expression="$body/*[1]">
<property name="messageType"
value="application/xacml+json"
scope="axis2"
type="STRING"
description="messageType"/>
<send/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence>
<log level="full" category="WARN"/>
</faultSequence>
</target>
<description/>
</proxy>
Result :
After hitting proxy URL in browser: - Only one response as below:
<jsonObject><viewableIdentityAttributes><Email>Kevin.Mollo#companyb.com</Email><cn>Kevin Mollo</cn><Last Name>Mollo</Last Name><First Name>Kevin</First Name></viewableIdentityAttributes><listAttributes>First Name</listAttributes><listAttributes>Last Name</listAttributes><listAttributes>Email</listAttributes><listAttributes>cn</listAttributes></jsonObject>
In server logs:
[2016-07-14 11:46:35,057] INFO - LogMediator To: http://www.w3.org/2005/08/addr
essing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:3beaaf16-7b94-4e
08-a3e0-7605869572c7, Direction: response, Component = Application1, Payload: {"vi
ewableIdentityAttributes":{"Email":"Kevin.Mollo#companyb.com","cn":"Kevin Mollo"
,"Last Name":"Mollo","First Name":"Kevin"},"assignedRoles":[],"listAttributes":[
"First Name","Last Name","Email","cn"]}
[2016-07-14 11:46:35,057] INFO - LogMediator To: http://www.w3.org/2005/08/addr
essing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:c878c7db-ad4c-49
46-94d6-75aebc75ad8e, Direction: response, Component = Application1, Payload: {"vi
ewableIdentityAttributes":{"Email":"Michelle.Lassauze#companyb.com","cn":"Michel
le Lassauze","Last Name":"Lassauze","First Name":"Michelle"},"assignedRoles":[],
"listAttributes":["First Name","Last Name","Email","cn"]}
As we can see I get responses from both the endpoints in server logs.
As per analysis, I feel to make it work properly and get the responses from both the endpoints, we need change the following:
1. Using call mediator instead of send if we have multiple endpoints to be called.
2. Using enrich mediator to store the responses.
I tried following the above approaches but I am unable to get the expected results as I am not sure how to use enrich mediator in this case.
Please help me in fixing the above issues.
Clone mediator will be used to send identical copies of message to different endpoints.
Iterate mediator will be used to send message chunks of one particular message to different endpoints.
Enrich mediator will be used to change message (Ex: removing content, adding etc.) [1]
Check your endpoints and check whether they provide proper responses to work with aggregate mediator.
I add sample scenario here. You can test that with your ESB pack to understand the above three mediators usage. You just have to start 2 instances of SimpleStockQuote service [2] and publish message to proxy via SOAPUI.
<proxy name="ScatterGatherProxy" startOnLoad="true" trace="disable" transports="https http">
<description/>
<target>
<inSequence>
<clone>
<target>
<sequence>
<send>
<endpoint name="vendorA">
<address uri="http://localhost:9001/services/SimpleStockQuoteService/"/>
</endpoint>
</send>
</sequence>
</target>
<target>
<sequence>
<send>
<endpoint name="vendorB">
<address uri="http://localhost:9002/services/SimpleStockQuoteService/"/>
</endpoint>
</send>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<log level="full"/>
<aggregate>
<completeCondition>
<messageCount min="2"/>
</completeCondition>
<onComplete expression="//m0:return"
xmlns:m0="http://services.samples" xmlns:m1="http://services.samples/xsd">
<enrich>
<source clone="true" xpath="//m0:return[not(preceding-sibling::m0:return/m1:last <= m1:last) and not(following-sibling::m0:return/m1:last < m1:last)]"/>
<target type="body"/>
</enrich>
<send/>
</onComplete>
</aggregate>
</outSequence>
</target>
</proxy>
If you need further assistance, please attach more details like responses of your service.
[1] http://dilshanilive.blogspot.com/2016/03/enrich-mediator-wso2-esb.html
[2] https://docs.wso2.com/display/ESB490/Setting+Up+the+ESB+Samples#Starting%20the%20Axis2%20server

Role based access control to WSO Message Broker Hierarchical Topic

I've recently started experimenting with a Message exchange between WSO2 ESB's via WSO2's MB for a requirement. Created a JMS sender Proxy Service which concatenates endpoint URL based on SOAP Input (used Header property and defaultEndpoint).
On Message Broker:
Have set up a Hierarchical topic as
Root|
Node1
Node2
With 3 users and their specific roles as Root, Node1, Node2. Requirement is Node 1 should be able to subscribe for both Node 1 and Root, Similarly for Node2, Only Node2 and Root.
The problem is When creating a proxy service subscriber can only set it to subscribe one Node only (Root or Node1 or Node2). Tried setting destination as Root.# but then All Nodes are subscribed (even when Node USer is not set to Subscribe the other based on Role based Topic access). Following is the code for subscriber
enter code here
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="Subscriber_Node2"
transports="jms"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<log level="full"/>
<log level="custom" separator="###">
<property name="STATE"
value="**************** RECEIVED AT Node 2 ***************"/>
</log>
<drop/>
</inSequence>
<outSequence/>
<faultSequence>
<log level="custom">
<property name="text" value="An unexpected error occured"/>
<property name="message" expression="get-property('ERROR_MESSAGE')"/>
<property name="code" expression="get-property('ERROR_CODE')"/>
<property name="detail" expression="get-property('ERROR_DETAIL')"/>
<property name="exception" expression="get-property('ERROR_EXCEPTION')"/>
</log>
</faultSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="java.naming.factory.initial">
org.wso2.andes.jndi.PropertiesFileInitialContextFactory
</parameter>
<parameter name="transport.jms.ConnectionFactory">
Store2TopicConnectionFactory</parameter>
<parameter name="java.naming.provider.url">
repository/conf/jndi.properties</parameter>
<parameter name="transport.jms.DestinationType">topic</parameter>
<parameter name="transport.jms.Destination">HQ.Store_2</parameter>
<description/>
</proxy>
jndi.properties:
connectionfactory.Node1TopicConnectionFactory = amqp://Node1:Node1#clientID/carbon?
brokerlist='tcp://localhost:5680'
connectionfactory.Node2TopicConnectionFactory = amqp://Node2:Node2#clientID/carbon?
brokerlist='tcp://localhost:5680'
connectionfactory.RootTopicConnectionFactory = amqp://Root1:Root1#clientID/carbon?
brokerlist='tcp://localhost:5680'
topic.Root = Root
topic.Root.Node1 = Root.Node1
topic.Root.Node2 = Root.Node2
Is there a way a Subscriber can subscribe to Multiple Topics in a hierrarchy and its access be controlled by User and Role?

How We Can Break a String in Wso2esb using Xpath

I wish to break a string in wso2esb using xpath
my input like this
<property name="Message" value="assetname:ups,assetcode:452chi,assetid:548935,assetvalue:215" scope="default"/>
i need break in same property using xpath
i need like this
assetname:ups
assetcode=452chi
assetid=54895
assetvalue=215
for this i tried with tokenize function but wso2esb showing errors
my configure file
<proxy xmlns="http://ws.apache.org/ns/synapse" name="Xpathcheck" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="max" value="1" scope="default" type="STRING"/>
<property name="min" value="1" scope="default" type="STRING"/>
<property name="MessageText" expression="fn:concat('Assetid:',get-property('min'),',','Assetname:',get-property('max'))" scope="default" type="STRING"/>
<property name="Tokenize" expression="fn:tokenize(get-property('Messagetext'),',')" scope="default" type="STRING"/>
<log>
<property name="MessageText" expression="get-property('MessageText')"/>
<property name="Tokenize" expression="get-property('Tokenize')"/>
</log>
</inSequence>
<outSequence/>
</target>
<description></description>
</proxy>
But its throwing errors like this u have any idea for this i need store this in Db table as a one field which look like separate lines
error is
ERROR - SynapseXPath Evaluation of the XPath expression fn:tokenize(get-property('Messagetext'),',') resulted in an error
org.jaxen.UnresolvableException: No Such Function tokenize
tokenize is a function comes with XPath 2.0. To enable XPath 2.0 functions uncomment the following entry in the synapse.properties file which is located at $ESB_HOME/repository/conf directory
synapse.xpath.dom.failover.enabled=true
then you have to specify the mediator as follows,
<property name="Message" value="a,b,c,d,e" scope="default"/>
<property xmlns:fn="http://www.w3.org/2005/xpath-functions" name="Tokenize" expression="fn:tokenize(syn:get-property('Message'),',')" scope="default" type="STRING"/>
I dont think this can be done through XPath, XPath is to navigate elements in an XML. You can do this by using a script mediator and write a JS to break the property values.
use the following to access the ESB params from the script mediator
<script language="js"> var test_param = mc.getProperty('Message')
Use the following to retrieve the params within the script mediator back to the ESB
mc.setProperty("param1",var1)
mc.setProperty("param2",var2)
Use the javascript to carry out the required string manupulations

Problem with evaluating XPath while using Apache Synapse

I'm trying to run Apache Synapse samples on ubuntu 11.04 64-bit and I have found problem with evaluating XPath expression in sample nr 2.
My XPath expression:
$ <definitions xmlns="http://ws.apache.org/ns/synapse"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ws.apache.org/ns/synapse http://synapse.apache.org/ns/2010/04/configuration/synapse_config.xsd">
<sequence name="main">
<switch source="//m0:getQuote/m0:request/m0:symbol" xmlns:m0="http://services.samples">
<case regex="IBM">
<!-- the property mediator sets a local property on the *current* message -->
<property name="symbol" value="Great stock - IBM"/>
</case>
<case regex="MSFT">
<property name="symbol" value="Are you sure? - MSFT"/>
</case>
<default>
<!-- it is possible to assign the result of an XPath expression as well -->
<property name="symbol" expression="fn:concat('Normal Stock - ', //m0:getQuote/m0:request/m0:symbol)"/>
</default>
</switch>
<log level="custom">
<!-- the get-property() XPath extension function allows the lookup of local message properties
as well as properties from the Axis2 or Transport contexts (i.e. transport headers) -->
<property name="symbol" expression="get-property('symbol')"/>
<!-- the get-property() function supports the implicit message headers To/From/Action/FaultTo/ReplyTo -->
<property name="epr" expression="get-property('To')"/>
</log>
<!-- Send the messages where they are destined to (i.e. the 'To' EPR of the message) -->
<send/>
</sequence>
It is run on following data:
$ <soapenv:Body><m0:getQuote xmlns:m0="http://services.samples"><m0:request><m0:symbol>IBM</m0:symbol></m0:request></m0:getQuote></soapenv:Body></soapenv:Envelope>
And result is:
2011-08-08 15:37:04,227 [-] [HttpClientWorker-1] DEBUG SwitchMediator XPath : //m0:getQuote/m0:request/m0:symbol evaluates to :
2011-08-08 15:37:04,227 [-] [HttpClientWorker-1] DEBUG SwitchMediator None of the switch cases matched - executing default
while it should go to:
$<case regex="IBM">
<!-- the property mediator sets a local property on the *current* message -->
<property name="symbol" value="Great stock - IBM"/>
</case>
Does anyone knows what can be the problem? I have installed that ubuntu few days ago, so there is possibility, that there is something missing on that system.
Try with full xpath..
<switch xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m0="http://services.samples" source="//soapenv:Envelope/soapenv:Body/m0:getQuote/m0:request/m0:symbol">

Resources