I am absolutly new in WSO2 and I am working on a WSO2 Enterprise Integrator project containing this ESB project section (I think that my question is only related to ESB).
So my doubt is: I have an XML file defining an API. The flow starts with a payloadFactory mediator, something like this:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/xxxTest2" name="xxxTest2" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET">
<inSequence>
<!-- Create empty message to get all samples from DSS -->
<!-- Get Sample ID -->
<payloadFactory media-type="xml">
<format>
<body/>
</format>
<args>
<arg evaluator="xml" expression="get-property('uri.var.int_val')" xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
...............................................................
...............................................................
...............................................................
</api>
This API handle request that I can send using CURL:
curl -v http://MY_SERVER_IP:8280/xxxTest2
Reading the official documentation:
https://docs.wso2.com/display/ESB481/PayloadFactory+Mediator
I know that the payload factory is used to create a content message that have to be sent using something that send an HTTP Request (correct me if this is a wrong assertion).
My doubt is:
the content of this message is empty because it is:
<format>
<body/>
</format>
But it contains this argument defined into the args element:
<args>
<arg evaluator="xml" expression="get-property('uri.var.int_val')" xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd"/>
</args>
So I have 2 doubts:
1) Reading the previous documentation this argument should contain the content value of a $1 variable in the previous payload content (the ... element). But it is empty. It doesn't contain any variable. So why I find this argument?
2) The value of the argument is retrieved with an expression:
expression="get-property('uri.var.int_val')"
What exactly does this expression? What is retrieving?
For passing an argument to Payload factory mediator, you must declare it in the part.
Let's say you are passing an argument 'name' to the payload factory mediator, your source should look like
<payloadFactory media-type="xml" xmlns="http://ws.apache.org/ns/synapse">
<format>
<name_of_the_element xmlns="">$1</name_of_the_element>
</format>
<args>
<arg evaluator="xml"
expression="get-property('uri.var.int_val')" literal="false"/>
</args>
Here, the value of uri.var.int_val will be passed to the element $1. PAyload factory mediator uses positional parameters for its arguments i.e., $1,$2,....$N.
If there is no arguments in the payload you create, you can delete the part in the source. So if your payload is just , then your source will look like,
<payloadFactory media-type="xml">
<format>
<body/>
</format>
</payloadFactory>
The expression expression="get-property('uri.var.int_val')" extracts the value of int_val from the URI parameters.
Thanks
Related
I am unable to get PayloadFactory mediator to transform input arguments to what the service expects.
I have a requirement to support legacy APIs by looking at input request and providing default values for new parameters or perform data type transformations at the WSO2 layer. For the purpose of PoC, I am trying to send an input argument val while the service expects value but I do not see the input argument correctly reaching the service. Below is the in sequence I am using:
<definitions xmlns="http://ws.apache.org/ns/synapse" name="sample1">
<sequence name="sample1">
<in>
<!-- using payloadFactory mediator to transform the request message -->
<payloadFactory media-type="xml">
<format>
<tem:GetData xmlns:tem="http://localhost/LegacyService/Service1.svc">
<tem:value>$1</tem:value>
</tem:GetData>
</format>
<args>
<arg xmlns:tem="http://localhost/LegacyService/Service1.svc" expression="//tem:val"/>
</args>
</payloadFactory>
</in>
<send/>
</sequence>
</definitions>
Here is the web request that I am making using SOAPUI:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:GetData>
<!--Optional:-->
<tem:val>2000</tem:val>
</tem:GetData>
</soapenv:Body>
</soapenv:Envelope>
How can I troubleshoot this?
The namespace in the request and the namespace in the payloadfactory when looking up the value from the request are different. Therefore your expression is searching an element that does not exist in the request.
xmlns:tem="http://localhost/LegacyService/Service1.svc"(payloadFactory argument)
vs
xmlns:tem="http://tempuri.org/"(request message)
You need to make sure the expression in your argument matches the request message
<args>
<arg xmlns:tem="http://tempuri.org/" expression="//tem:val"/>
</args>
In wso2 ESB after calling an endpoint I am getting the response as number(ex: 78) with header application/json, if without processing the response if i send in out sequence it works fine i'll get the same response. But if I include any mediators for processing in between it'll throw exceptions like Could not save JSON payload. Invalid input stream found. A single string or number is not valid in some cases So, it may throwing the exception but this bug is resolved in wso2 EI 6.2.
So now I am able to process the response but if I use script mediator to get that value it shows {}. If i use json-eval($.) then also i am not able to get the value, also with xpath i am not able to get.
So how to get that response(the value in number) for further processing in wso2 ei, by using script mediator or by using json path.
If you are certain that the response only contains a number with the content-type header with application/json. you can take the value to a property as below.
<property name="RESPONSE_NUMBER" expression="//jsonValue" scope="default" type="INTEGER"/>
When you need this value somewhere else in the mediation flow you can take the value from the property(in this case RESPONSE_NUMBER) as below.
$ctx:RESPONSE_NUMBER
Here is a sample API which demonstrates how you can take the response value and use it in the mediation flow.
<api xmlns="http://ws.apache.org/ns/synapse" name="SampleAPI" context="/getNumber">
<resource methods="GET">
<inSequence>
<send>
<endpoint>
<http method="GET" uri-template="http://www.mocky.io/v2/5b02cc2c3000006600cee384"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<property name="RESPONSE_NUMBER" expression="//jsonValue" scope="default" type="INTEGER"/>
<payloadFactory media-type="json">
<format>{"Id": $1}</format>
<args>
<arg evaluator="xml" expression="$ctx:RESPONSE_NUMBER"/>
</args>
</payloadFactory>
<send/>
</outSequence>
</resource>
</api>
You can call the API with below curl command:
curl -v http://localhost:8280/getNumber
I set a property type is string as below:
<property name="result" scope="default" type="STRING" value="0"/>
<payloadFactory media-type="xml">
<format>
<jsonObject>
<result>$1</result>
</jsonObject>
</format>
<args>
<arg evaluator="xml" expression="$ctx:result"/>
</args>
</payloadFactory>
But the response result is integer.What happened?
{
"result": 0
}
Property value is not a response content. How you make your response body? May be you use payloadFactory?
You can found something about json types in payload https://www.yenlo.com/blog/wso2torial-json-magic-in-wso2-esb-5.0.0 and wso2 esb - problems with XML to JSON conversion
You've specified your payloadFactory to use xml. I am assuming later on, you convert that xml to json.
In xml, there is no concept of "string" vs "integer" - unless you use xsd's - so when the ESB/EI converts the xml to json, it will convert the value to an integer if it sees a number, and a string if it doesn't.
XML -> JSON conversion is not type safe. Can you not use a json payloadFactory:
<payloadFactory media-type="json">
<format>{ "result": "$1" }</format>
<args>
<arg evaluator="xml" expression="$ctx:result"/>
</args>
</payloadFactory>
In WSO2 ESB 490 I have wrote the simple API:
<api xmlns="http://ws.apache.org/ns/synapse" name="paramsTest" context="/params">
<resource methods="GET" uri-template="/p?try={params_list}">
<inSequence>
<property name="params_list" expression="get-property('uri.var.params_list')"/>
<log level="full">
<property name="The input params : " expression="get-property('params_list')"/>
</log>
<payloadFactory media-type="json">
<format>{"res_body":"$1"}</format>
<args>
<arg evaluator="xml" expression="get-property('params_list')"/>
</args>
</payloadFactory>
<respond/>
</inSequence>
</resource>
</api>
It work fine when access by URL:
http://localhost:8290/params/p?try=one
and response {"res_body":"one"}
But when access by this URL :
http://localhost:8290/params/p?try=one,two
It response nothing, and it seems ESB didn't process the request because of parameters "try=one,two" separate by comma.
How can make ESB process this URL?(parameters separate by comma)
AFAIK you need to encode the comma with %2C when using with url params.
e.g.
http://localhost:8290/params/p?try=one%2Ctwo
If you get the parameter list via a property you will get %2C encoded values with parameters. Have a look at the working example mentioned below.
<resource methods="POST" uri-template="?sessionId={id}">
<inSequence>
<property name="sessionId" expression="$url:sessionId"/>
Extract parameters one by one as mentioned above.
I have received an message response in WSO2 from Endpoint when i send the data. Im newbie in WSO2. Can you show me how to get the value of Job tag (00000559) on message?
Below is received message.
Thanks & Regards,
[2013-08-24 13:25:08,295] INFO - LogMediator To: , WSAction: http://www.abc.com/ns/transaction/Post, SOAPAction: http://www.abc.com/ns/transaction/Post,
MessageID: urn:uuid:1e939de3-3ade-4aea-afdf-9e1defcae760, 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><PostResponse
xmlns="http://www.syspro.com/ns/transaction/"><PostResult><?xml version="1.0" encoding="Windows-1252"?>
<postjob Language='05' Language2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' Version='6.1.058' OperatorPrimaryRole=' '>
<Item>
<Job>00000559</Job>
<ItemNumber> 1</ItemNumber>
</Item>
<StatusOfItems>
<ItemsProcessed>1</ItemsProcessed>
<ItemsInvalid>0</ItemsInvalid>
</StatusOfItems>
</postjob>
</PostResult></PostResponse></soap:Body></soap:Envelope>
You can use XPATH expressions to get the value of any tag.
If you need to log the value in job tag, use below in the out sequence
<log>
<property name="VM_LOG" expression="//PostResponse//PostResult//postjob//Item/Job"/>
</log>
If you need to send it as the response, you can simply use the payload factory mediator inside the out sequence
<payloadFactory media-type="xml">
<format>
<results xmlns="">$1</results>
</format>
<args>
<arg evaluator="xml" expression="//PostResponse//PostResult//postjob//Item/Job"/>
</args>
</payloadFactory>
Finally you can add the send mediator.
<send/>
Thanks.