What should be Switch Mediator's source path? - wso2

Scenario
I've two XML-based data files, I need to use a switch mediator in my API to direct the xml file to its respective mediation flow which is implemented in the same API. The XMLs are shown below:
XML - 1
<Table>
<Trademarks>
<FileNbr>574988</FileNbr>
<DateOfRegistration>03-DEC-21</DateOfRegistration>
<Class> 43 </Class>
<ApplicantName>Ramada International, Inc.</ApplicantName>
<Address>22 Sylvan Way Parsippany, New Jersey 07054</Address>
<Title>RAMADA RESIDENCES</Title>
<Status>Trademark registered</Status>
</Trademarks>
<Trademarks>
<FileNbr>524918</FileNbr>
<DateOfRegistration>03-DEC-21</DateOfRegistration>
<Class> 37 </Class>
<ApplicantName>Muhammad Usman, Trading as, IMAMDIN ASSOCIATES</ApplicantName>
<Address>Imamdin Associates, 89/6-R,</Address>
<Title>IMAM DIN</Title>
<Status>Trademark registered</Status>
</Trademarks>
</Table>
XML - 2
<Table>
<Copyright>
<applicationno>1641/2001</applicationno>
<applicationdate>11/15/2001 12:00:00 AM</applicationdate>
<TitleEnglish>DURA PLUS</TitleEnglish>
<applicantname>FARMIGEA PAKISTAN (PVT) LTD.</applicantname>
<class>ARTISTIC WORK</class>
<City>LAHORE</City>
<Country>PAKISTAN</Country>
<status>Application Registered</status>
</Copyright>
<Copyright>
<applicationno>1644/2001</applicationno>
<applicationdate>11/15/2001 12:00:00 AM</applicationdate>
<TitleEnglish>OCUGEL FARMIGEA</TitleEnglish>
<applicantname>FARMIGEA PAKISTAN (PVT) LTD.</applicantname>
<class>ARTISTIC WORK</class>
<City>LAHORE</City>
<Country>PAKISTAN</Country>
<status>Application Registered</status>
</Copyright>
</Table>
Question
I need to specify the Source XPath for the Switch mediator. In
the above scenario how can I differentiate between the two XML data files
based on the second nodes i-e Trademarks & Copyright.?
Which property should I used for the above requirement?

You can use the xpath local-name() function, like below. But keep in mind, that only checks the first element after <Table>. I also like to use upper-case() function, to avoid upper/lower case issues. And the cases are with regex start ^ and end $ matches. Working example below.
<switch source="upper-case(local-name(//Table/*))" xmlns:ns="http://org.apache.synapse/xsd">
<case regex="^TRADEMARKS$">
<payloadFactory media-type="json">
<format>{"Trademarks":"DoSomething"}</format>
</payloadFactory>
</case>
<case regex="^COPYRIGHT$">
<payloadFactory media-type="json">
<format>{"Copyright":"To something else"}</format>
</payloadFactory>
</case>
<default>
<payloadFactory media-type="json">
<format>{"Error":"Invalid table name"}</format>
</payloadFactory>
</default>
</switch>
<respond/>

Related

Eclipse removes drop mediator after send

I tried to implement a validation with FAULT in it something like this
<on-fail>
<makefault version="soap11">
<code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
<reason value="Invalid Request!!!"/>
<role/>
</makefault>
<log level="full"/>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<send/>
<drop/>
</on-fail>
therefore I added DROP after SEND what function just as I wanted (without DROP I just recived FAULT message but the process did not stop what resulted into invoking some End points with incorrect inputs)
Then I needed to check on something and I open the same sequence in Eclipse and discovered that DROP got removed.
I tried to drag and drop DROP but got an error message that the SEND mediator cannot be followed by another mediator.
why?
do you happen to know a better way how to implement SEND + DROP so there is not a risk that I lose this when I open it in Eclipse?
thx a lot!
You do not need to add a Drop Mediator after a Send. It is invalid to add any mediators after the Send mediator, since the message context will be dropped after the send. May be instead of a SEND mediator you can try adding a Respond Mediator. Your use case is not so clear.
In Eclipse Developer Studio, we cannot specify any mediator after SEND mediator/ RESPOND mediator/ DROP mediator. This is because, ideally mediation flow should not continue after those mediators.
For your case, can you try CALL mediator[1] instead of SEND mediator followed by DROP mediator as follows
<on-fail>
<makefault version="soap11">
<code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
<reason value="Invalid Request!!!"/>
<role/>
</makefault>
<log level="full"/>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<call/>
<drop/>
</on-fail>
https://docs.wso2.com/display/ESB490/Call+Mediator

WSO2 ESB- PayloadFactory for different operations

I have a backend service with multiple operations. (for example,echoInt and echoString). I want to replace input value for both of them with predefined variables(in the inSequence) with PayloadFactory mediator.
How can i define payloadfactory for different operations?
when i define two payloadfactory mediator for each of them, only the last mediator works for it's operation. when i call other opertaion, this error occures:
wso2 namespace mismatch
operation1:
<p:echoString xmlns:p="http://echo.services.core.carbon.wso2.org">
<in>$1</in>
</p:echoString>
operation2:
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in>$1</in>
</p:echoInt>
My inSequense:
<inSequence>
<payloadFactory media-type="xml">
<format>
<p:echoString xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">teststr</in>
</p:echoString>
</format>
<args/>
</payloadFactory>
<payloadFactory media-type="xml">
<format>
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">1111</in>
</p:echoInt>
</format>
<args/>
</payloadFactory>
</inSequence>
with above inSequense, output result for both operations is '1111':
<ns:echoStringResponse xmlns:ns="http://echo.services.core.carbon.wso2.org">
<return>1111</return>
</ns:echoStringResponse>
thanks in advance
The second Payload factory replaces the first.
If you want to use each of them in a different case, you should define them in a Switch mediator.
You can use a property to get the input that defines which case you should use, then use regex to match the property value. Or you could skip the property and enter the expression in the Switch source.
At the end it would look similar to:
<inSequence>
<property expression="/default/expression" name="input_string" scope="default" type="STRING"/>
<switch source="get-property('input_string')">
<case regex="[\w\s]+">
<payloadFactory media-type="xml">
<format>
<p:echoString xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">teststr</in>
</p:echoString>
</format>
<args/>
</payloadFactory>
</case>
<default>
<payloadFactory media-type="xml">
<format>
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">1111</in>
</p:echoInt>
</format>
<args/>
</payloadFactory>
</default>
</switch>
<respond/>
</inSequence>
If you want call two operations in same time, you should use the clone or iterate Mediator, and use the aggregate Mediator in the outsequence.
The reason you use the two payloadFactory, only last one works, is that one request only have one message context, this mean, you only can send one soap message to back end in same time. This mean the last payloadFactory will override the first one.
Clone or iterate Mediator will clone or split one message context to multiple message context, then you can send multiple soap message to back end services. Because of you got multiple message context, then you should use the aggregate Mediator to aggregate these multiple responses into one message context after back end services return the result.

Rebuilding the initial message using the payload factory mediator

I'm involved in a proxy service development using WSO2.
In my sequence I've saved the initial current message in a property using the following:
<property name="InitialMessage" expression="$body" scope="default" type="STRING"/>
and now I need to rebuild the initial message using the payload factory mediator. Am I right? What are some considerable alternatives?
Could someone show me the right syntax in this case?
yes your method is correct, But I would suggest you to save only the required properties from your incoming message and use them in building the new message. Sample Syntax is given below
<payloadfactory>
<format>
<m:checkpriceresponse xmlns:m="http://services.samples/xsd">
<m:code>$1</m:code>
<m:price>$2</m:price>
</m:checkpriceresponse>
</format>
<args>
<arg expression="//m0:symbol" xmlns:m0="http://services.samples/xsd">
<arg expression="//m0:last" xmlns:m0="http://services.samples/xsd">
</arg></arg></args>
</payloadfactory>
I've solved my problem using the enrich mediator: Here you are how ...
I've saved my initial message in a property InitialMessage in this manner ...
<property name="InitialMessage" expression="$body" scope="default" type="STRING"/>
and after I've used the enrich mediator in this manner
<enrich>
<source type="property" clone="true" property="InitialMessage"/>
<target type="body"/>
</enrich>
It's working ...
I hope this could be useful ...

Out Sequence -- Enrich mediator is not working as expected

I trying to build a application which includes service chaining. When i try to merge the responses and do the extra transformation on the merged response.. i see unintended response.I see the response i merged along with my xslt transformation outcome
For example:
If i have added "abc" to my existing outcome using enrich -> sibling to body option, after i do transformation, i still see "abc" getting appended.
Please see my code below
<enrich>
<source clone="false" type="custom" xpath="get-property('poecResp')"/>
<target action="sibling" type="body"/>
</enrich>
<log category="INFO" level="full" separator=","/>
<xslt key="conf:Response_V1.xslt"/>
<log category="INFO" level="full" separator=","/>
in the last log i print i see the sibling i added still remains.
I see the issue is with xslt. i should choose the "Source XPATH". But not sure still why my Enrich component is not working.

wso2: Looking for XSLT transformation working example

Can some one point me to a working example of xsl transformation using the proxy services xslt mediator option.
Basically, my requirement is, i will have a request where i will get some data which determines the routing and after that from other elements of requested data i have to re frame soap request to trigger another bpel service.
Please let me know the better approach to this.
You can very well use XSLT transformation in your sequence, using XSLT Mediator.
In your sequence file you can specify the XSLT file to tranform the request. Sample sequence code snippet:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="SampleInterceptorSequence">
<in>
<log level="full" category="DEBUG">
<property name="sequence" value="inSequence-Request Before XSLT" />
</log>
<xslt key="RequestTranformerXSLT" />
<log level="full" category="DEBUG">
<property name="sequence" value="inSequence-Request After XSLT" />
</log>
<send>
<endpoint key="MyActualServiceEPR" />
</send>
</in>
Your xslt would contain the style for the actual request to be formed for hitting the end point reference.
Further if you can check this nice article of web service chaining to get a real time idea of xslt mediation.
Web Service Chaining from WSO2 ESB Developers
Hope this helps.
Thanks.
Find the sample below..
http://wso2.org/project/esb/java/4.0.0/docs/samples/message_mediation_samples.html#Sample8