How to do addition of two numbers in wso2esb - xpath

I am using wso2esb4.7.0
i wish to do addition of 2 numbers using wso2esb for that i have written my proxy but its not working
my proxy is like this
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="Addition"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="Value1"
expression="//Value1/text()"
scope="default"
type="STRING"/>
<property name="Value2"
expression="//Value2/text()"
scope="default"
type="STRING"/>
<property name="Result"
expression="fn:sum(get-property('Value1'),get-property('Value2'))"
scope="default"
type="STRING"/>
<log>
<property name="RESULT" expression="get-property('Result')"/>
</log>
</inSequence>
<outSequence/>
</target>
<description/>
</proxy>
i logged it the result is given errors :
ERROR - SynapseXPath Evaluation of the XPath expression fn:sum(get-property('Value1'),get-property('Value2')) resulted in an error
org.jaxen.FunctionCallException: sum() requires one argument.
at org.jaxen.function.SumFunction.call(SumFunction.java:99)
at org.jaxen.expr.DefaultFunctionCallExpr.evaluate(DefaultFunctionCallExpr.java:177)
at org.jaxen.expr.DefaultXPathExpr.asList(DefaultXPathExpr.java:102)
at org.jaxen.BaseXPath.selectNodesForContext(BaseXPath.java:674)
at org.jaxen.BaseXPath.selectNodes(BaseXPath.java:213)
at org.jaxen.BaseXPath.evaluate(BaseXPath.java:172)
and I tried with this also
<property name="Result"
expression="fn:sum(//Value1/text(),//Value2/text()))"
scope="default"
type="STRING"/>
Even this is also giving errors how would i reach to addition goal and my curl command like this
curl -v -H "Accept: application/json" -H "Content-Type:application/json" -H "ModifiedOn:0" -H "userid:-1899999899" -H "username:vikash|214057357158656" -H "password:gbadmin" -d '{"Value1":"2","Value2":"45"}' http://youtility2-desktop:8282/services/Addition

You can use the script mediator to achieve this. First you can set the two values as you have done above. Then in the script mediator you can add them and set to the required property.
Complete proxy with this approach;
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="Addition"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="Value1"
expression="//Value1/text()"
scope="default"
type="INTEGER"/>
<property name="Value2"
expression="//Value2/text()"
scope="default"
type="INTEGER"/>
<script language="js">
var value1 = mc.getProperty("Value1");
var value2 = mc.getProperty("Value2");
var result = value1 + value2;
mc.setProperty("Result", result);
</script>
<log>
<property name="RESULT" expression="get-property('Result')"/>
</log>
</inSequence>
<outSequence/>
</target>
<description/>
</proxy>

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="Addition"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="Value1"
expression="//Value1/text()"
scope="default"
type="INTEGER"/>
<property name="Value2"
expression="//Value2/text()"
scope="default"
type="INTEGER"/>
<script language="js">
var value1 = parseInt(mc.getProperty("Value1"));
var value2 = parseInt(mc.getProperty("Value2"));
var result = value1 + value2;
mc.setProperty("Result", result);
</script>
<log>
<property name="RESULT" expression="get-property('Result')"/>
</log>
</inSequence>
<outSequence/>
</target>
<description/>
</proxy>

Related

change original payload with wso2 esb

I saved the following structure on a property du wso2:
<ELEMENT>
<ELEMENT_2>
<ELEMENT_3>
<ID> 173993 </ID>
</ELEMENT_3>
</ELEMENT_2>
</ELEMENT>
I want to bring TEMP only to children:
<TEMP>
<NAME>GEORGE</NAME>
<COGNOME>MENDEZ</COGNOME>
<BUSINESSNAME/>
<CHANNEL>X091</CHANNEL>
</TEMP>
I want to add them right after the <ELEMENT_2>
FINAL RESULTS:
<ELEMENT>
<ELEMENT_2>
<NAME>GEORGE</NAME>
<COGNOME>MENDEZ</COGNOME>
<BUSINESSNAME/>
<CHANNEL>X091</CHANNEL>
<ELEMENT_3>
<ID> 173993 </ID>
</ELEMENT_3>
</ELEMENT_2>
</ELEMENT>
Thanks
Can you check if your requirement is achieved with the following proxy configuration.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="enrichProxy"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<property name="initial_payload" scope="default">
<ELEMENT xmlns="">
<ELEMENT_2>
<ELEMENT_3>
<ID>173993</ID>
</ELEMENT_3>
</ELEMENT_2>
</ELEMENT>
</property>
<call>
<endpoint>
<http uri-template="http://run.mocky.io/v3/7c578a1d-5427-4325-9f00-4ad7bb80dd04"/>
</endpoint>
</call>
<log level="custom">
<property expression="$body//TEMP/*" name="******"/>
</log>
<respond/>
</inSequence>
</target>
<description/>
</proxy>
Remove external tag with xpath wso2
update
Here I have enriched the second property (..) back to the body using a enrich mediator.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="enrichProxy"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<property name="initial_payload" scope="default">
<ELEMENT xmlns="">
<ELEMENT_2>
<ELEMENT_3>
<ID>173993</ID>
</ELEMENT_3>
</ELEMENT_2>
</ELEMENT>
</property>
<property name="second_payload" scope="default">
<TEMP xmlns="">
<NAME>GEORGE</NAME>
<COGNOME>MENDEZ</COGNOME>
<BUSINESSNAME/>
<CHANNEL>X091</CHANNEL>
</TEMP>
</property>
<enrich>
<source clone="true" property="second_payload" type="property"/>
<target type="body"/>
</enrich>
<enrich>
<source clone="true" xpath="$body//TEMP/*"/>
<target action="child" xpath="$ctx:initial_payload//ELEMENT_2"/>
</enrich>
<log level="custom">
<property expression="$ctx:initial_payload" name="******"/>
</log>
<respond/>
</inSequence>
</target>
<description/>
</proxy>

WSO2 missing value when logging property

I'm currently stuck with the following.
Goal 1: get the URL in the log
Goal 2 use it in the send mediator
Could you guys help me with both?
XML file:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<meta:MetaDataType xmlns:meta="http://teswt.nl/xmlschemas/meeeeta/0.1">
<meta:Version>6.3</meta:Version>
<meta:FixLevel>0.0</meta:FixLevel>
<meta:Endpoint>http://555.555.555.55:8088/sal</meta:Endpoint>
</meta:MetaDataType>
</soap:Header>
The code in the proxy insequence so far:
<property xmlns:meta="http://teswt.nl/xmlschemas/meeeeta/0.1" expression="$header//meta:MetaDataType/meta:Endpoint" name="URL" scope="default" type="STRING"/>
<log level="custom">
<property xmlns:meta="http://teswt.nl/xmlschemas/meeeeta/0.1" expression="get-property('URL')" name="URL"/>
</log>
<send>
<endpoint>
<address format="soap11" uri="http://555.555.555.55:8088/sal"/>
</endpoint>
</send>
It prints the following:
INFO {org.apache.synapse.mediators.builtin.LogMediator} - URL =
I have tested the given request and the XPath expression in EI 6.6.0 server and I could observe that the XPath is working as expected and logging the URL.
Request
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<meta:MetaDataType xmlns:meta="http://teswt.nl/xmlschemas/meeeeta/0.1">
<meta:Version>6.3</meta:Version>
<meta:FixLevel>0.0</meta:FixLevel>
<meta:Endpoint>http://555.555.555.55:8088/sal</meta:Endpoint>
</meta:MetaDataType>
</soap:Header>
<soap:Body/>
</soap:Envelope>
Proxy service
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="test"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<property xmlns:meta="http://teswt.nl/xmlschemas/meeeeta/0.1"
expression="$header//meta:MetaDataType/meta:Endpoint"
name="URL"
scope="default"
type="STRING"/>
<log level="custom">
<property xmlns:meta="http://teswt.nl/xmlschemas/meeeeta/0.1"
expression="get-property('URL')"
name="URL"/>
</log>
</inSequence>
</target>
<description/>
</proxy>
Could you please enable the wire logs and check if the desired request is received by the service. You can also add a <log level="full"/> before extracting the URL to check the payload received.
In addition to that, what is the EI version that you are using

getting token from cognito and caching in wso2 Enterprise Intigrator

I need to get a token from Cognito but I don't know how to get it through enterprise integrator. I have client_id and client_secet and endpoint also. But I 'm not able to get the token seems I'm not calling the endpoint properly with proper parameter.
After getting the token I need to cache it till the token expires so I don't have to call again and again
here is the code I'm trying
<cache id="cache-sample" scope="per-host" collector="false" hashGenerator="org.wso2.carbon.mediator.cache.digest.DOMHASHGenerator" timeout="5000">
<implementation type="memory" maxSize="1000"/>
</cache>
<header name="client_id" scope="transport" value="XXXXXXXXXXXXXXXXX"/>
<header name="client_secret" scope="transport" value="XXXXXXXXXXXXXXXXXXX"/>
<header name="Content-Type" scope="transport" value="application/json"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<call>
<endpoint>
<address uri="https://xcxxxxxxxxxx.auth.us-east-1.amazoncognito.com/oauth2/token"/>
</endpoint>
</call>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<cache scope="per-host" collector="true"/>
<respond/>
<?xml version="1.0" encoding="UTF-8"?>
<api context="/api/myService" name="myService-api" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/getToken">
<inSequence>
<script language="js"><![CDATA[var payload = mc.getPayloadXML();
var log = mc.getServiceLog();
var client_id = payload..*::client_id.toString();
var client_secret = payload..*::client_secret.toString();
mc.setProperty("client_id", client_id);
mc.setProperty("client_secret", client_secret);]]>
</script>
<payloadFactory media-type="json">
<format/>
<args/>
</payloadFactory>
<property name="ContentType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<property expression="fn:concat($ctx:client_id,':',$ctx:client_secret)" name="credentials" scope="default" type="STRING"/>
<property expression="fn:concat('Basic ', base64Encode($ctx:credentials))" name="Authorization" scope="transport" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<property name="FORCE_POST_PUT_NOBODY" scope="axis2" type="BOOLEAN" value="true"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<cache
collector="false"
hashGenerator="org.wso2.carbon.mediator.cache.digest.DOMHASHGenerator"
id="cognito-token"
scope="per-host"
timeout="3600">
<onCacheHit>
<log level="custom">
<property expression="/" name="[usage-service-api]:: CHACHE HIT"/>
</log>
<respond/>
</onCacheHit>
<implementation maxSize="50" type="memory"/>
</cache>
<call>
<endpoint>
<http method="post" uri-template="https://xxxxxxxxxxx.amazoncognito.com/oauth2/token?grant_type=client_credentials"/>
</endpoint>
</call>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<cache collector="true" id="cognito-token" scope="per-host"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
For first Call cache miss will happen in that case it will call the endpoint and store it in the cache
for the second call and onwards till the time expires for the same call it will hit the cache i.e. Cache hit then It will respond from onCacheHit mediator
<onCacheHit>
<respond/>
</onCacheHit>
and
But after cache hit it will skip any execution of any statement written after cache Mediator. So So keep it in some other sequence if you are writing in some sequence
You can have more than one resources in API.
If you want to know how to call this API then see this getting cognito acces_token with wso2 esb
<log level="custom">
<property expression="/" name="[usage-service-api]:: CHACHE HIT"/>
</log>
The above block of code logs the content of the cache on CACHE HIT

WSO2 get value from service response

I have this rest api in WSO2 ESB:
<api xmlns="http://ws.apache.org/ns/synapse" name="RestApi" context="/rest">
<resource methods="POST GET" uri-template="/view/{symbol}" protocol="http">
<inSequence>
<log level="full"/>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.w3schools.com/webservices/">
<soapenv:Header/>
<soapenv:Body>
<web:FahrenheitToCelsius>
<web:Fahrenheit>$1</web:Fahrenheit>
</web:FahrenheitToCelsius>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('uri.var.symbol')"/>
</args>
</payloadFactory>
<property name="DISABLE_CHUNKING" value="true" scope="axis2"/>
<send>
<endpoint>
<address uri="http://www.w3schools.com/webservices/tempconvert.asmx" format="soap11"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<property name="messageType" value="application/json" scope="axis2"/>
<property name="msgbody" expression="$body" scope="default" type="STRING"/>
<log level="custom">
<property name="To" expression="get-property('msgbody')"/>
</log>
<payloadFactory media-type="json">
<format>{"Status":"evgeni"}</format>
<args/>
</payloadFactory>
<send/>
</outSequence>
<faultSequence/>
</resource>
</api>
The important part is the <outSequence></outSequence>
The property <property name="msgbody" expression="$body" scope="default" type="STRING"/> returns the response from the soap service. It looks like this:
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<FahrenheitToCelsiusResponse xmlns="http://www.w3schools.com/webservices/">
<FahrenheitToCelsiusResult>4.44444444444444</FahrenheitToCelsiusResult>
</FahrenheitToCelsiusResponse>
</soap:Body>
I want to get just the value of FahrenheitToCelsiusResult (4.44444444444444). How can I do that?
I tried:
<property xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
name="msgbody"
expression="$body/soap:Body/FahrenheitToCelsiusResponse/FahrenheitToCelsiusResult"
scope="default" type="STRING"/>
but it returns an empty string.
You have to provide the namespace in the xpath expression as in below
<property expression="//ns:FahrenheitToCelsiusResult"
name="msgbody" scope="default" type="STRING"
xmlns:ns="http://www.w3schools.com/webservices/"/>
For more information please refer to this link
Thanks.
<property name="tempValue" expression="//*[local-name()='FahrenheitToCelsiusResult']" scope="default" type="STRING"/>

How to break/stop sequence if exception occurs in mediator using WSO2 ESB

i am trying to implement logic that if during execution of sequence any error occurs, like e.g JMS endpoint is invalid, So sequence should drop here and log the message.
The actual mediation is like below:
Validate-->Clone-->Log Clone mediation snapshot attached.
My Service Code is:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="AdapterService"
transports="jms"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log level="full" separator="..... XML Received..."/>
<validate source="//DOCUMENT03">
<schema key="conf:/DOCUMENT03_CUSTOM.xsd"/>
<on-fail>
<makefault version="pox">
<reason value="Invalid XML"/>
<detail>Error while validating XML at Adapter Service.</detail>
</makefault>
<log level="full" category="ERROR" separator="... XML Error..."/>
<drop/>
</on-fail>
</validate>
<clone>
<target>
<sequence>
<script language="js">mc.getEnvelope().getBody().getFirstElement().getFirstElement().getFirstElement().detach();</script>
<log level="full"/>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<send>
<endpoint>
<address uri=**"jms:/BookingMessage?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://1929.168.1.113:61616&transport.jms.DestinationType=queue"**
format="pox">
<timeout>
<duration>10</duration>
<responseAction>fault</responseAction>
</timeout>
<suspendOnFailure>
<errorCodes>101507,101505,101503</errorCodes>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>10</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<errorCodes>101508,101504</errorCodes>
<retriesBeforeSuspension>5</retriesBeforeSuspension>
<retryDelay>10</retryDelay>
</markForSuspension>
</address>
</endpoint>
</send>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>$1</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg xmlns:tns="http://com.sanomalearning/cdm/finance/generalledger/v1"
evaluator="xml"
expression="//DOCUMENT03/CMMHeader"/>
</args>
</payloadFactory>
<log level="full"/>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<send>
<endpoint key="conf:/CMMHeaderQueueUrl"/>
</send>
<log level="full" separator="Message Sent to Queue"/>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence>
<log level="custom" separator=",">
<property name="text" value="***FAult Handler***"/>
</log>
<property name="SET_ROLLBACK_ONLY" value="true" scope="axis2"/>
<drop/>
<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>
<drop/>
</faultSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="transport.jms.ConnectionFactory">myQueueConnectionFactory</parameter>
<parameter name="transport.jms.DestinationType">queue</parameter>
<parameter name="transport.jms.Destination">AdapterService.01.Request.Queue</parameter>
<description/>
</proxy>
Now when i execute this service after receiving request from queue, it is not sending message to invalid queue but sending message to second Url. Now i want if message is not sent to invalid endpoint then sequence should dropped. The invalid url is Bold.
AFAIK you can not define two send mediators under the same target in one clone mediator instead you have to define those inside two different targets.
Also would be helpful if you can elaborate your requirement a bit more. For a solution with regard to JMS endpoint is invalid issue what you can do is define a drop mediator inside the fault sequence.

Resources