WSO2 ESB cannot obtain url parameters that contains comma - wso2

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.

Related

WSO2 Integration has multiple resources, POST request works but GET request doesn't and gives 202 Accepted

Use Case: I recently came upon a problem while creating an integration in WSO2 Integration Studio,
I have an API with 2 resources, one is a POST, the other is a GET
Problem: when I run the integration to test it, the POST request works fine while the GET request gives me the code 202 accepted without even calling the endpoint
Code: this is my code, in the second sequence the log is printed alright but the call isn't executed
<api context="/flow" name="companyflow" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/createIssues">
<inSequence>
<call>
<endpoint key="IssueEndpoint"/>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
<resource methods="GET" uri-mapping="/getIssues">
<inSequence>
<log>
<property name="text" value="HelloThere"/>
</log>
<call>
<endpoint key="issuesList"/>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Tip:: I suspect the problem may be related to uri-template and uri-mapping but I'm not sure
There is no issue with your integration configurations or syntax. Normally you get a 202 when you have an error in the flow. So I'm suspecting your Endpoint reference is wrong. Double check whether the key is correct and the endpoint is deployed to MI. (Make sure it's selected in the Capp pom file)
<call>
<endpoint key="issuesList"/>
</call>

Paralel processing in WSO2 EI 6.2

I'm developing a healthcheck API that needs to call several endpoints. The idea is that, if any of those EPs fail, I have to capture the fault and incorporate that into the response. I thought about creating a main sequence that calls other leaf sequences, and each leaf sequence has it own fault sequence.
This diagram should make things clearer:
seqA (faultSsqA)
/
mainSeq - seqB (faultSeqB)
\ seqC (faultSeqC)
If all the sequences process successfully, everything goes well and I'm able to process the response, however, if there's a fault within one of the leaf sequences, the corresponding faultsequence is executed, but I don't know how to return the flow of execution back to the main sequence. What I want is that, if a exception occurs in sequence B, fault sequence B is executed and then the execution flow goes back to the main sequence and then to sequence C.
Even better it would be if I could execute all the leaf sequences in pararel, and just gather all the results in the end. I know that iterate mediator sort of do that, but from what I understand the semantics are not the same of what I want.
Anyone has thoughts on this?
EDIT: so it seems the clone mediator is what I'm looking for, however I'm still not able to get it working the way I need to. Since I'll be connecting to different platforms, the response formats are distinct. Also, I need to treat situations such as timeouts, 500 response codes, etc. Therefore, I can't simply call an endpoint from each target - for each backend platform I've created a sequence that does all this logic, and populate some properties so that I can populate the final response ("platform A = up", etc).
My expectation would be that all the target sequences would be processed in paralel
This is my main sequence. I use a clone mediator and target it to 2 different sequences, which do the actual invocation of the EP and treat the response (I'm using only 2 for now, but in the future will be many more). The sequences also update some variables to reflect the status of the backend platforms ("platform A = up", etc).
<sequence name="inSequence_healthCheck" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<clone id="healthCHeck">
<target>
<sequence>
<sequence key="healthCheck_wacs"/>
</sequence>
</target>
<target>
<sequence>
<sequence key="healthCheck_thesys"/>
</sequence>
</target>
</clone>
<loopback/>
</sequence>
This is one of the target sequences (it' very simple for now, but there should be more logic in it). Notice that I populate the property wacsStatus depending on the response.
<sequence name="healthCheck_wacs" onError="faultSequence_healthCheck_wacs" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<call>
<endpoint key="gov:ClientEquipments/endpoints/WACS/wacs_healthCheck.endpoint.xml"/>
</call>
<switch source="$axis2:HTTP_SC">
<case regex="2\d\d|4\d\d">
<property name="wacsStatus" scope="default" type="BOOLEAN" value="true"/>
</case>
<default>
<property name="wacsStatus" scope="default" type="BOOLEAN" value="false"/>
</default>
</switch>
</sequence>
And this is my outSequence, that does the aggregate:
<sequence name="outSequence_healthCheck" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<log>
<property name="step" value="START outSequence_healthCheck"/>
<property expression="$ctx:wacsStatus" name="wacsStatus"/>
<property expression="$ctx:thesysStatus" name="thesysStatus"/>
<property expression="$ctx:phStatus" name="phStatus"/>
<property expression="$ctx:naStatus" name="naStatus"/>
</log>
<property name="info" scope="default">
<ns:Information xmlns:ns="http://wso2.com"/>
</property>
<aggregate id="healthCHeck">
<completeCondition>
<messageCount max="-1" min="2"/>
</completeCondition>
<onComplete enclosingElementProperty="info" expression="s11:Body/child::* | s12:Body/child::*"
xmlns:m0="http://services.samples" xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:s12="http://www.w3.org/2003/05/soap-envelope">
<log level="full"/>
</onComplete>
</aggregate>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<payloadFactory media-type="json">
<format>
{
"WACS" : "$1",
"thesys" : "$2"
}
</format>
<args>
<arg evaluator="xml" expression="$ctx:wacsStatus"/>
<arg evaluator="xml" expression="$ctx:thesysStatus"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property name="HTTP_SC" scope="axis2" type="STRING" value="200"/>
<respond/>
</sequence>
My expectation would be that the aggregate mediator would wait for all the target sequences to execute, by then all the properties would be properly populated and I could use the payloadFactory to properly format the response. However, from the logs I can see that, even though the aggregate does aggregate all the responses from the target sequences, the properties are not properly populated and therefore the response is not correct.
Thanks.
Pedro
You should try an iterate mediator/clone & aggregate mediator (scatter-gather pattern) construction. The iterate allows you to execute multiple sequences in paralel while the aggregate will collect the responses. You can have the separate sequences deal with fault handling and return either the expected response or some fault. You can then check the aggregated result for any faults.
Here are a few samples:
Yenlo Blog
WSO2 Architecture Team

In wso2 esb how to get a single number(integer) value

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

Mapping optional query params in WSO2 ESB API resource

I have to mapping query params to send request to endpoint in API resource in WSO2 ESB.
Those query params are optional. For example, the following are examples of calls to resource:
http://server:port/service?q1={q1}
http://server:port/service?q2={q2}&q3={q3}
I need to have a single resource to do this.
How can I do this?
Basically, I have to read query params in request and put it in the call to endpoint uri.
You can have dynamic URIs using url-mapping attribute.
Here is an example:
<api xmlns="http://ws.apache.org/ns/synapse" name="test_api" context="/testService">
<resource methods="GET" url-mapping="/*">
<inSequence>
<log level="full">
<property name="paramQ1" expression="$ctx:query.param.q1"></property>
<property name="paramQ2" expression="$ctx:query.param.q2"></property>
<property name="paramQ3" expression="$ctx:query.param.q3"></property>
</log>
<send>
<endpoint>
<address uri="http://localhost:9766/services/"></address>
</endpoint>
</send>
</inSequence>
<outSequence>
<send></send>
</outSequence>
</resource>
</api>
To validate the presence of those query params its possible to use Filter Mediator. A good example of it can be found here.
Hope it helps.

Can we store a string in a text file in wso2esb?

I have a text file on my local system I wish to append the data in particular file as synchronously.
I have tried many ways, but it's not working.
ESB has this future in Oracle SOA. We can add in FILE ADAPTER. In ESB it's neither giving errors nor expected result.
My configuration is like this:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="FileWrite" transports="http,vfs" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<log>
<property name="OUT_ONLY" value="true"/>
</log>
</inSequence>
<outSequence>
<log>
<property name="OUT_ONLY" value="true"/>
</log>
<payloadFactory>
<format>
<error>error404</error>
</format>
</payloadFactory>
<send>
<endpoint>
<address uri="vfs:file:///home/youtility2/Desktop/Errorlog"/>
</endpoint>
</send>
</outSequence>
</target>
<parameter name="transport.vfs.ReplyFileURI">file:///home/user/test/out? transport.vfs.Append=true</parameter>
<parameter name="transport.PollInterval">10</parameter>
<parameter name="transport.vfs.FileNamePattern">Errorlog.text</parameter>
<parameter name="transport.vfs.ContentType">text/xml</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<parameter name="transport.vfs.ReplyFileName">Errorlog.xml</parameter>
<description></description>
</proxy>
Actually I kept a log mediator in outSequence. The inSequence mediator is not sending the data in to the outSequence process not forwarding into outSequence. That's why I think that the above configuration is not working.
Any reference for this?
I tried above configuration in inSequence also. It's giving errors like this:
ERROR - Axis2Sender Unexpected error during sending message out
org.apache.axis2.AxisFault:
The VFS transport doesn't support synchronous responses. Please use
the appropriate (out only) message exchange pattern
Please refer to this link.
The issue is, you are setting a property inside a log mediator which is a predefined property, (ie:OUT_ONLY) which is used to indicate the request is only the "out-only" request. So, system, wont expect the response back. That is why, you are not getting anything in your outsequence.
DO NOT USE the predefined properties in the Log mediator,which will cause issues.
Keep some text in the log meditaor to indictae the flow of the message.
eg:
<inSequence>
<log>
<property name="INSEQUENCEEEEEEE" value="********"/>
</log>
</inSequence>
Like wise keep different descriptive log in the outsequence and see whether you are getting the message there, without any issue.