wso2 esb filter with xquery expression inside property - wso2-esb

I want to use this expression in WSO2 property mediator
sum(//datas//queryResponse[CODEAGENCE='01003']//NOMBER)
I have done this to count without apply filter
fn:sum($ctx:datas//*[local-name()='queryResponse']//*[local-name()='NOMBRE'])

Your question is unclear. Do you want to count sum of NOMBRE field, using xquery on a property, that contains XML? If so, here is a sample API. You can call it from POSTMAN or browser http://{YourWSO2SErver}:8280/Test/testSO_57326564
The result is {"sum":"340.0"} on sample data.
Please note, that the property "datas" has OM type.
<api xmlns="http://ws.apache.org/ns/synapse" name="Test" context="/Test">
<resource methods="GET" uri-template="/testSO_57326564">
<inSequence>
<log level="full"/>
<payloadFactory media-type="xml">
<format>
<datas xmlns="">
<queryResponse>
<CODEAGENCE>01003</CODEAGENCE>
<NOMBRE>100</NOMBRE>
</queryResponse>
<queryResponse>
<CODEAGENCE>01003</CODEAGENCE>
<NOMBRE>240</NOMBRE>
</queryResponse>
<queryResponse>
<CODEAGENCE>01002</CODEAGENCE>
<NOMBRE>10000000</NOMBRE>
</queryResponse>
</datas>
</format>
<args/>
</payloadFactory>
<property name="datas" expression="$body/*[1]" type="OM" description="property must be an OM type"/>
<property name="sum" expression="fn:sum($ctx:datas//queryResponse[CODEAGENCE=01003]/NOMBRE)"/>
<payloadFactory media-type="json">
<format> {"sum":"$1"} </format>
<args>
<arg evaluator="xml" expression="get-property('sum')"/>
</args>
</payloadFactory>
<respond/>
</inSequence>
</resource>
</api>

Related

OnComplete in Aggregate sequence not triggered after the Iteration sequence

I'm building a microservice where I have a main sequence that first reads a json file and then goes into iteration sequence that is connected to an aggregator sequence with an ID. Here is the order from the main sequence:
<property expression="json-eval($)" name="ORIGINAL_PAYLOAD" scope="default" type="STRING"/>
<sequence key="data-iterate-seq"/>
<property name="aggregatedResponses" scope="default">
<batch_response/>
</property>
<sequence key="data-aggregate-seq"/>
The problem I'm facing is that once it goes into iterate it first triggers the code in aggregate that is outside of OnComplete, then it goes back and does the iterations and never goes to the OnComplete neither it goes back to the main sequence. I managed to make it continue with the main sequence using continueParent=true but this way it never goes into OnComplete of the aggregation sequence. I have also tried switching the onComplete expression to $body/*[1] and //jsonObject but it didn't work Edit: neither did the <send/> and <loopback/> operators.
Here is my iterator
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="data-iterate-seq" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<iterate attachPath="json-eval($)" expression="json-eval($.records)" id="requestIterator" preservePayload="true">
<target>
<sequence>
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="json" expression="$"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<log level="custom" separator="
">
<property expression="json-eval($)" name="BODY_INSIDE_ITERATE"/>
</log>
<!-- Prepare Payload -->
<property expression="json-eval($.recordId)" name="recordId" scope="default" type="STRING"/>
<property name="entitySetName" scope="default" type="STRING" value="accounts"/>
<property expression="concat(get-property('msdynamics365.resource'),'/api/data/',get-property('msdynamics365.api.version'),'/')" name="patch-url" scope="axis2" type="STRING"/>
<payloadFactory media-type="json">
<format>{"batch_response": "{ "relativeUrlTemplate": "{{apiUrl}}{{entitySetName}}{{entityRecordId}}",
"method": "PATCH",
"entitySetName": "$1",
"entityRecordId": "$2",
"data": {
"name":"$3",
"email":"$4"
}
}}
</format>
<args>
<arg evaluator="xml" expression="$ctx:entitySetName"/>
<arg evaluator="xml" expression="$ctx:recordId"/>
<arg evaluator="json" expression="$.data.name"/>
<arg evaluator="json" expression="$.data.emailaddress1"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<log level="full"/>
<log level="custom" separator="
">
<property name="Results" value="Number of iterations"/>
</log>
</sequence>
</target>
</iterate>
</sequence>
and my aggregator:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="data-aggregate-seq" onError="data-fault-seq" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<aggregate id="requestIterator">
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" enclosingElementProperty="aggregatedResponses" expression="json-eval($)" xmlns:ns="http://org.apache.synapse/xsd">
<property expression="json-eval($)" name="aggregatedResponses" scope="default" type="STRING"/>
<log level="full">
<property expression="json-eval($)" name="OUT_SEQUENCE_AGGREGATED_RESPONSE"/>
</log>
<log level="full">
<property expression="get-property('aggregatedResponses')" name="Responses"/>
</log>
</onComplete>
</aggregate>
<log level="custom">
<property expression="json-eval($)" name="FINAL_PAYLOAD"/>
<property expression="get-property('aggregatedResponses')" name="aggregated_Response"/>
</log>
</sequence>
Any suggestions on what I'm doing wrong or anything that might help would be really appreciated!
Thank you in advance!!
According to the documentation, you need to use a call or send mediator inside the Iterate mediator to continue the message flow.
In Iterate you need to send the split messages to an endpoint to
continue the message flow.
For me, it seems you are only transforming the message payload. Hence you can use Foreach mediator to do that without Iterate mediator.

how to send response as String using class mediator in wso2 esb

In my project I created some proxy.There transport type is tcp.
My response is
{
"BillingSystem": {
"request_id": "20114140080000011479122000",
"request_timestamp": "12102012121200",
"response_timestamp": "12102012121300",
"action": "AddSubscription",
"username": "Cellcard ",
"result_code": "0",
"result_desc": "Success"
}
}
I catch this response using class mediator and create WZ2OCS2:1:14:14008:1:#1479122000# using that response. I need to send this string to tcp client. I set this String in the class meditor
context.setProperty("responseClientValue", responseClientValue);
After set this value in class mediator I used payload factory mediator and after that property mediator.
<payloadFactory description="" media-type="xml">
<format>
<name xmlns="">$1</name>
</format>
<args>
<arg evaluator="xml" expression="get-property('responseClientValue')"/>
</args>
</payloadFactory>
property mediator
<property name="messageType" scope="axis2" type="STRING" value="application/text"/>
When I run project Its show xml code
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><name>WZ2OCS2:1:14:14008:1:#1479122000#</name></soapenv:Body></soapenv:Envelope>?
Here is my proxy service
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="SurepayBillingErrorHandlingProxy" startOnLoad="true" transports="tcp" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<class description="" name="esb.cellcard.billing.SurepayMediator"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<send>
<endpoint key="SurpayBillingEP"/>
</send>
</inSequence>
<outSequence>
<class name="esb.cellcard.billing.ResponseRequestId"/>
<payloadFactory description="" media-type="xml">
<format>
<name xmlns="">$1</name>
</format>
<args>
<arg evaluator="xml" expression="get-property('responseClientValue')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/text"/>
<send/>
</outSequence>
<faultSequence/>
</target>
<parameter name="transport.tcp.responseClient">true</parameter>
<parameter name="transport.tcp.inputType">string</parameter>
<parameter name="transport.tcp.recordDelimiter">?</parameter>
<parameter name="transport.tcp.contentType">text/plain</parameter>
<parameter name="transport.tcp.port">6050</parameter>
<parameter name="transport.tcp.recordDelimiterType">character</parameter>
</proxy>
How can I get only string value. Thank you
Change your payloadFactory like this :
<payloadFactory>
<format>
<text xmlns="http://ws.apache.org/commons/ns/payload">$1</text>
</format>
<args>
<arg evaluator="xml" expression="$ctx:responseClientValue"/>
</payloadFactory>
Change property messageType like this :
<property name="messageType" scope="axis2" type="STRING" value="text/plain"/>
(see axis2.xml, by default, the PlainTextFormatter class is associated with text/plain : <messageFormatter contentType="text/plain" class="org.apache.axis2.format.PlainTextFormatter"/>)

WSO2ESB: How to add <?xml into the message sent to POX endpoint

I'm using wso2ei 6.0.0 and I have a simple task - send specific xml message via POST to the endpoint.
I have API configured like this:
<api xmlns="http://ws.apache.org/ns/synapse" name="glisTest" context="/glisTest">
<resource methods="GET" uri-template="/{sampleid}">
<inSequence>
<property name="PRESERVE_WS_ADDRESSING" value="false"/>
<payloadFactory media-type="xml">
<format>
<register />
</format>
</payloadFactory>
<log level="full"/>
<property name="messageType" value="application/xml" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="post" scope="axis2" type="STRING"/>
<send>
<endpoint>
<address uri="https://localhost/manager" encoding="UTF-8" format="pox"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full"/>
<send/>
</outSequence>
</resource>
</api>
But service is expected
<?xml version="1.0" encoding="UTF-8" ?>
to be inserted at the beginning and wso2 do not do it (I just added debug logging for org.apache.synapse.transport.http.wire and I see it simple send
<register/>
As result, it does not recognize message as an xml and returm me error.
Question - how to tell synapse to add this special xml header to the message?

WSO2 ESB - Api to Soap transformation

I would like to expose an API (REST) on ESB that traslate the request to a SOAP service.
My Api is definined in this way :
<api xmlns="http://ws.apache.org/ns/synapse" name="__test" context="/mytest">
<resource methods="GET" uri-template="/{symbol}">
<inSequence>
<property name="symbol" expression="get-property('uri.var.symbol')"/>
<payloadFactory media-type="xml">
<format>
<ser:getQuote xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
<ser:request>
<xsd:symbol>$1</xsd:symbol>
</ser:request>
</ser:getQuote>
</format>
<args>
<arg evaluator="xml" expression="get-property('symbol')"/>
</args>
</payloadFactory>
<log level="full"/>
<send>
<endpoint>
<wsdl service="SimpleStockQuoteService" port="SimpleStockQuoteServiceHttpEndpoint"
uri="http://localhost:9000/services/SimpleStockQuoteService?wsdl"/>
</endpoint>
</send>
</inSequence>
</resource>
</api>
But when i invoke the url with http://:8280/mytest/WSO2 I heve this error on console
<soapenv:Reason xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Text xml:lang="en-US">
The endpoint reference (EPR) for the Operation not found is /services/SimpleStockQuoteService.SimpleStockQuoteServiceHttpEndpoint/WSO2?request= and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator.
</soapenv:Text>
</soapenv:Reason>
Because the esb append the WSO2 part of the request to URL.
How I can solve this ?
Thanks
You can follow this guide for achieving this. Note that the soap action header should be added as follows and endpoint is different.
<header name="Action" value="urn:getQuote"/>
Find the complete solution API below,
<api xmlns="http://ws.apache.org/ns/synapse" name="__test" context="/mytest"><resource methods="GET" uri-template="/{symbol}">
<inSequence>
<property name="symbol" expression="get-property('uri.var.symbol')"/>
<payloadFactory media-type="xml">
<format>
<ser:getQuote xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
<ser:request>
<xsd:symbol>$1</xsd:symbol>
</ser:request>
</ser:getQuote>
</format>
<args>
<arg evaluator="xml" expression="get-property('symbol')"/>
</args>
</payloadFactory>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<log level="full"/>
<header name="Action" value="urn:getQuote"/>
<send>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService" format="soap11"/>
</endpoint>
</send>
</inSequence></resource></api>
If you want to use the WSDL url directly, you can achive this using WSO2 API Manager and it can be easily tried in WSO2 API Cloud. There is a similar question here.

Issue in getting response back while connecting to Oracle DB in WSO2 esb

I am working on sample application in WSO2 esb
which connects to Oracle Database and return the response of a query. Below mentioned is my service. Issue I am facing is I am not getting the response back after execution of service.However I am able to see the value returned as a query response, but not able to render it in response document.
Can anybody suggest, what I am missing?
DB credentials fields have been hashed.
Proxy :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="getEmployeeDetails"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true" scope="default" type="BOOLEAN"/>
<log level="full" category="DEBUG"/>
<dblookup>
<connection>
<pool>
<password>****</password>
<user>****</user>
<url>****</url>
<driver>oracle.jdbc.xa.client.OracleXADataSource</driver>
</pool>
</connection>
<statement>
<sql>select firstname from employee where lastname = 'pawar'</sql>
<result name="firstname" column="firstname"/>
</statement>
</dblookup>
<log level="custom">
<property name="firstname" expression="get-property('firstname')"/>
</log>
<payloadFactory media-type="xml">
<format>
<GetEmployeeDetailsResponse xmlns="">
<out>$1</out>
</GetEmployeeDetailsResponse>
</format>
<args>
<arg evaluator="xml" expression="get-property('firstname')"/>
</args>
</payloadFactory>
</inSequence>
<outSequence>
<log level="full" category="DEBUG"/>
</outSequence>
</target>
<publishWSDL uri="file:/development/data/wso2/wsdl/Employee.wsdl"/>
<description/>
</proxy>
You have to send back the message generated by your payloadFactory in your inSequence :
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<send/>
Your mediation is "OUT_ONLY", so, your outSequence will never been executed