WSO2 ESB payload from property - wso2

I'm trying to create a payload from a property content:
<payloadFactory media-type="xml">
<format>$1</format>
<args>
<arg evaluator="xml" expression="get-property('Response')"/>
</args>
</payloadFactory>
WSO2 ESB is not accepting this as a valid payload format. What can I do to achieve this?

You can't use Payload Factory for this. It requires a wrapping XML tag like this.
<payloadFactory media-type="xml">
<format><Root>$1</Root></format>
<args>
<arg evaluator="xml" expression="get-property('Response')"/>
</args>
</payloadFactory>
But you can do what you want with Enrich mediator.
<enrich>
<source clone="false" type="property" property="ORIGINAL_PAYLOAD"/>
<target action="replace" type="body"/>
</enrich>
Here is a similar sample.

May be because of the type of the 'Response' Clovis.
I'm using this and found no problem.
<property description="requestBk" expression="json-eval($.)" name="requestBk" scope="default" type="STRING"/>
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="$ctx:requestBk"/>
</args>
</payloadFactory>
One other tip. Use $ctx: instead of get-property method for a better performance. Because get-property looks in the registry also.
And yes! as Bhathiya and Maria suggested you can use the Enrich mediator also as mentioned below.
Copy the original payload to a property using the Enrich mediator.
<enrich>
<source clone="false" type="body"/>
<target action="replace" type="property" property="ORGINAL_PAYLOAD"/>
</enrich>
Then whenever you need the original payload, you replace the message body with this property value using the Enrich mediator as follows:
<enrich>
<source clone="false" type="property" property="ORIGINAL_PAYLOAD"/>
<target action="replace" type="body"/>
</enrich>

Related

WSO2 EI new xml tag using Enrich mediator and when xml tag takes dynamically

Is it possible to add new xml tag to xml payload using enrich mediator.
my sample payload -
<courses>
<id>181</id>
<formatted_name>Learning</formatted_name>
<score>0</score>
<status>in_progress</status>
<issued_certificate />
<from_timestamp>1626083705</from_timestamp>
<to_timestamp />
</courses>
New tag would be
<link> www.google.com </link>
I cannot use inline as the source since link is taken dynamically.
So I'm adding new tag to a payload and then property.
<payloadFactory media-type="xml">
<format>
<link xmlns="">$1</link>
</format>
<args>
<arg evaluator="xml" expression="get-property('login_link')"/>
</args>
</payloadFactory>
<property description="Get login link payload" expression="//root/*" name="login_link_xml" scope="default" type="STRING"/>
// get original payload back
<enrich description="Restore original payload">
<source clone="false" property="course_payload" type="property"/>
<target type="body"/>
</enrich>
// assign property as a new node inside the courses
<enrich>
<source clone="true" property="login_link_xml" type="property"/>
<target action="child" type ="custom" xpath="//courses"/>
</enrich>
This gives the same payload after enrich
You can do it in a bit different way. Create your 'tag' as property type OM, using xpath expresion and function: concat, with coded char
<property name="my_link" value="devintegra.com" scope="default" type="STRING"/>
<property name="linkNode"
type="OM"
expression="concat('<link>',get-property('my_link'),'</link>')"
scope="default" />
And with that property you can enrich your body:
<enrich>
<source type="property" clone="true" property="linkNode"/>
<target action="child" xpath="//courses"/>
</enrich>
That should work as you expect.

Sending multipart form data by WSO2 EI version 6.6 to a Rest API

I need some help here. I'm trying to send a multipart form data to a rest API by WSO2 EI (version 6.6). I'm following this https://docs.wso2.com/display/EI660/PayloadFactory+Mediator#PayloadFactoryMediator-Example6:UploadingafiletoanHTTPendpointviaamultipartrequest
It sends a file to the API with a success message as a result however the file is corrupted and we cannot open it. I had tried to send both PDF and PNG with the same issue. When I open the corrupted pdf file with notepad++, I can see base 64 code inside it. So I tried to decode the string before sending it to the API with base64Decode(string encoded value) but still, the PDF is corrupted. Is there any suggestion for this?
I used to work with ESB 5.0.0 but that version couldn't send the multipart because of missing boundary issue so I had to upgrade to a newer version. I may miss something here, can you please help me? thanks in advance.
My configuration is here:
<target>
<inSequence>
<enrich>
<source clone="true" type="body"/>
<target property="originalBody" type="property"/>
</enrich>
<property name="messageType" scope="axis2" type="STRING" value="multipart/form-data"/>
<property expression="fn:base64Decode(get-property('originalBody'))" name="content" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<root xmlns="">
<ModuleReference>DD</ModuleReference>
<FormattedAccount>002.2020.00160735.001</FormattedAccount>
<ExternalDocumentType>$1</ExternalDocumentType>
<Description>$2</Description>
<FileUpload xmlns="http://org.apache.axis2/xsd/form-data" filename="$3">$4</FileUpload>
<Filename>$5</Filename>
</root>
</format>
<args>
<arg value="1"/>
<arg value="test4"/>
<arg evaluator="xml" expression="$trp:FILE_NAME"/>
<arg evaluator="xml" expression="$ctx:content"/>
<arg value="test4.pdf"/>
</args>
</payloadFactory>
<header name="Authorization" scope="transport" value="Bearer ****"/>
<call blocking="true">
<endpoint>
<http method="POST" uri-template="http://XXXXX:XX/api/api/v2/recordmanagement/attachments"/>
</endpoint>
</call>
<property xmlns:ns="http://org.apache.synapse/xsd" expression="$axis2:HTTP_SC" name="Status2"/>
</inSequence>
</target>
<parameter name="transport.PollInterval">5</parameter>
<parameter name="transport.vfs.FileURI">file:///C:/WSO2/test/</parameter>
<parameter name="transport.vfs.ContentType">application/octet-stream</parameter>
<parameter name="transport.vfs.ActionAfterProcess">DELETE</parameter>
<parameter name="transport.vfs.FileNamePattern">.*\..*</parameter>
<description/>
</proxy>```
Normally the content will be shown as base64 encoded when it is sending the binary content of the file. Can you try defining the multipart/form-data messageType property after the payload factory mediator? (And remove the configurations related to decoding)
<property name="messageType" value="multipart/form-data" scope="axis2"/>
Refer this for more information.
I ran into a similar issue. Setting the below property in the mediation before sending the file to the endpoint, fixed my issue.
<property name="DECODE_MULTIPART_DATA" value="true" scope="axis2" type="BOOLEAN" />
The property will remove the base64 encoding done on the multi-part files by the EI.

WSO2ESB: Property setting not accepting empty value

Actually I'm trying to get an empty value when I set a Property in a sequence in WSO2 ESB with an empty string. I have tried many things but always get the result "null" or "\"\"" instead of "" when I get the property, here is my code:
<property value=""""
name="arq.general.DestinationSystem" scope="default"
type="STRING" xmlns:ns="http://org.apache.synapse/xsd"
xmlns:ns2="http://org.apache.synapse/xsd"/>
<property name="arq.general.ParentInstanceID" scope="default"
type="STRING" value=""/>
<property expression="get-property('NonExistentProperty')"
name="arq.functional.User"
scope="default" type="STRING"
xmlns:ns="http://org.apache.synapse/xsd"
xmlns:ns2="http://org.apache.synapse/xsd"/>
Please could you help?
Cheers,
Tony
++ the payload Factory:
<payloadFactory media-type="xml">
<format>
<MensajeAuditoria xmlns="">
<Timestamp>$1</Timestamp>
<TrackingID>$2</TrackingID>
<SourceApplication>$3</SourceApplication>
<OperationName>$4</OperationName>
<ParentInstanceID>$5</ParentInstanceID>
<InstanceID>$6</InstanceID>
<ServiceID>$7</ServiceID>
<FunctionalID>$8</FunctionalID>
<AdapterType>$9</AdapterType>
<AdapterPoint>$10</AdapterPoint>
<HostName>$11</HostName>
<User>$12</User>
</MensajeAuditoria>
</format>
<args>
<arg evaluator="xml" expression="get-property('SYSTEM_TIME')"/>
<arg evaluator="xml" expression="get-property('arq.general.TrackingID')"/>
<arg evaluator="xml" expression="get-property('arq.general.SourceApplication')"/>
<arg evaluator="xml" expression="get-property('arq.functional.OperationName')"/>
<arg evaluator="xml" expression="get-property('arq.general.ParentInstanceID')"/>
<arg evaluator="xml" expression="get-property('arq.general.InstanceID')"/>
<arg evaluator="xml" expression="get-property('arq.general.ServiceID')"/>
<arg evaluator="xml" expression="get-property('arq.functional.FunctionalID')"/>
<arg evaluator="xml" expression="get-property('arq.general.AdapterType')"/>
<arg evaluator="xml" expression="$func:AdapterPoint"/>
<arg evaluator="xml" expression="get-property('SERVER_IP')"/>
<arg evaluator="xml" expression="get-property('arq.functional.User')"/>
</args>
</payloadFactory>
</else>
</filter>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
Adding the factory result:
{
"MensajeAuditoria": {
"Timestamp": 1492777451830,
"TrackingID": "76b9858d-8421-4d7e-d2af-e8e411382e2e",
"SourceApplication": "API Manager",
"OperationName": null,
"ParentInstanceID": null,
"InstanceID": "76b9858d-8421-4d7e-d2af-e8e411382e2e",
"ServiceID": "PRX_PROY1_AEX_AltaCliente",
"FunctionalID": null,
"AdapterType": "AEXP",
"AdapterPoint": "PreActRequest",
"HostName": "172.16.3.97",
"User": null,
}}
I have achieved a work-around using JavaScript but it should be possible to set it in the property mediator, or may be with enrich.
<script language="js"><![CDATA[var payload = mc.getPayloadJSON();
if(payload.MensajeAuditoria.ParentInstanceID== null){
payload.MensajeAuditoria.ParentInstanceID="";
}
mc.setPayloadJSON(payload);
mc.setProperty("MyProperty","");]]></script>
If you get an XML solution, please let me know.
Thanks.
An other solution is to use "string" xpath function :
<property name="arq.general.ParentInstanceID" expression="string('')"/>
I have tried your payloadFactory and it turns out it works like a charm on 4.8.1 but it fails on 5.0.0. This is most likely a change in the JSON message builder that they use in the ESB. The problem is not on your empty property but in the automatic translation from XML to JSON that happens when you set the messageType property.
What you can do to solve this though is the make the payload mediator create json straight away as follows:
<payloadFactory media-type="json">
<format>
{"MensajeAuditoria":{
"Timestamp":$1,
"TrackingID":"$2"
...
}
}
</format>
<args>
<arg evaluator="xml" expression="get-property('SYSTEM_TIME')"/>
<arg evaluator="xml" expression="get-property('arq.general.TrackingID')"/>
...
</args>
</payloadFactory>
</else>
</filter>
This way you are in control of the quotes, and it will never put null there unless you actually want it there.
Hope this helps solve your problem
Good thing would be to use enrich mediator to map the json field to xml field if there is a vale for the incoming field.
Sample
<filter regex="true" source="boolean(get-property('START_DATE'))">
<then>
<enrich description="Add startDate tag">
<source clone="true" type="inline">
<org:startDate xmlns:org="urn:example.com/service/org"/>
</source>
<target action="child" xpath="//*[local-name()=get-property('RequestType')]"/>
</enrich>
<enrich description="populate startDate">
<source clone="true" property="START_DATE" type="property"/>
<target
xmlns:org="urn:example.com/servi`enter code here`ce/org" xpath="//org:startDate"/>
</enrich>
</then>
<else/>
</filter>

Preserve the original payload when calling a web service

I am struggling to figure out how to preserve a payload so that it is available after calling a web service within a sequence.
For example in the following sequence, after the “call” mediator fires the payload changes to what has been returned by the web service.
What I am looking to do is to enrich the original payload with the data that has been returned from the web service call.
All help is very much appreciated.
<log level="full"/>
<payloadFactory media-type="xml">
<format>
<Flight xmlns="">
<location_id>$1</location_id>
<FlightDistance/>
<Aircraft>
<AircraftAbbr/>
<LandingDistance/>
<TakeoffDistance/>
<AircraftRange/>
<AirframeHours/>
</Aircraft>
<Runways>
<Airport/>
</Runways>
</Flight>
</format>
<args>
<arg evaluator="xml" expression="get-property('OriginAirport')"/>
</args>
</payloadFactory>
<log level="full">
<property expression="get-property('OriginalPayload')" name="OriginalPayload"/>
</log>
<call blocking="true" description="">
<endpoint key="GetRunways"/>
</call>
<foreach expression="//d:Entries/d:Entry" id="feid" xmlns:d="http://ws.wso2.org/dataservice">
<sequence>
<log description="" level="full">
<property name="marker" value="marker"/>
</log>
<property expression="$body/Entry/runway_length" name="RunwayLength" scope="default" type="STRING"/>
<enrich>
<source clone="true" property="RunwayLength" type="property"/>
<target action="child" property="RunwayLength" type="property"/>
</enrich>
<log>
<property expression="get-property('RunwayLength')" name="PropertyValue"/>
</log>
</sequence>
</foreach>
use enrich mediator and store the payload in to property
<enrich>
<source type="body"/>
<target type="property" property="REQUEST_PAYLOAD"/>
</enrich>
https://docs.wso2.com/display/ESB481/Enrich+Mediator
To complete #Jenananthan answer:
Store original payload in a property
Call the webservice
Restore the original payload to body:
<enrich>
<source clone="false" type="property" property="ORIGINAL_PAYLOAD"/>
<target action="replace" type="body"/>
</enrich>

What is the Use of CallOut Mediator in WSO2ESB 4.7.0

I am using wso2esb4.7.0.i am working with different operations in single proxy i have found one example blog and i go through that.But i am not so clear about that blog my proxy is like this
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<log level="full">
<property name="M1" value="***************HITTING Transaction PROXY****************"/>
</log>
<property name="id" expression="//id/text()"/>
<property name="name" expression="//name/text()"/>
<payloadFactory media-type="xml">
<format>
<p:my_insert xmlns:p="http://ws.wso2.org/dataservice">
<xs:id xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:id>
<xs:name xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:name>
</p:my_insert>
</format>
<args>
<arg expression="get-property('id')" evaluator="xml"/>
<arg expression="get-property('name')" evaluator="xml"/>
</args>
</payloadFactory>
<callout serviceURL="https://localhost:9445/services/DTPDS/" action="urn:my_insert">
<source xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
<target xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
</callout>
<payloadFactory media-type="xml">
<format>
<p:pos_insert xmlns:p="http://ws.wso2.org/dataservice">
<xs:id xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:id>
<xs:name xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:name>
</p:pos_insert>
</format>
<args>
<arg expression="get-property('id')" evaluator="xml"/>
<arg expression="get-property('name')" evaluator="xml"/>
</args>
</payloadFactory>
<callout serviceURL="https://localhost:9445/services/DTPDS/" action="urn:pos_insert">
<source xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
<target xmlns:s12="http://www.w3.org/2003/05/soap-envelope" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xpath="s11:Body/child::*[fn:position()=1] | s12:Body/child::*[fn:position()=1]"/>
</callout>
<log level="full>
<property name="message" value="working"/>
</log>
<inSequence>
In callout meditor above Service url for hitting the endpoint and action is about endpoint operation But What is the use of
SOURCE and TARGET i tried to receive the endpoint response in to this source as well target also but i am unable to get response then what is the use of both
and how i am send my response to my client it means where can i get this response where i need to define my receive sequence Please refer me any clear explanation blog
'source' specifies the payload for the request message using an XPath expression or a registry key. The 'target' specifies a node at which the resulting payload(response) will be attached in the current message context.
By specifying as given in your sample config, response will be attached as the first child of the SOAP message body in message context.
The difference between callout mediator and send mediator is that callout mediator will return the response to the same sequence by doing a blocking call. In send mediator response is returned to the OutSequence in where you can send it back to the client.
So in here you can use the Send mediator (end of the inSequence) in order to send the message to the OutSequence. Then again do a send inside the outSequence to make it returned to the client.
ex:
add Below configs to end of the inSequence
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>
Then inside outSequence, again do a send.
<outSequence>
<send/>
</outSequence>