Is it possible to use the json from a response as a property and then use that to make a conditional statement? I looked into conditional router and sequence to make this happen but I don't know how to get the response and put it in a property mediator or just use it for conditional router.
example I have this response
{
"fruit": "apple"
}
and then I want to check if the key fruit is an apple.
if (response.fruit == "apple") {
callMediator();
} else {
callOtherMediator();
}
To set to property:
<property name="fruit" expression="//fruit"/>
To check, use Filter Mediator.
<filter source="$ctx:fruit" regex="apple">
<then>
<send/>
</then>
<else>
<drop/>
</else>
</filter>
Related
I'm working on an API and i would like to add a condition "higher than" like this :
<switch source="$ctx:myValue">
<case regex="$ctx:myValue > 1000">
...
</case>
<default/>
</switch>
Do you have any idea how to do this condition ? Thank you :)
Try the Filter mediator.
<filter xpath="get-property('myValue') > 1000">
<then>
... do something
</then>
<else>
... do something else
</else>
</filter>
Or, in case of the switch mediator, a simple regex for a value of 1000 or larger would be
[1-9][0-9]{3,}
However more specific requirements would be call for more complex regular expressions. So in the end a Filter mediator is probably your best bet in this case.
I answered my question by myself.
I used a script mediator like this :
<script language ="js">
<![CDATA[
var nbResultatJS = mc.getProperty('nbMessage');
var isSuperiorJS = 0;
if(nbResultatJS > 1000){
isSuperiorJS = 1;
}
mc.setProperty('isSuperior', isSuperiorJS);
]]>
</script>
<log level="custom">
<property name="MSG" expression="$ctx:isSuperior"/>
</log>
<switch source="$ctx:isSuperior">
<case regex="1.0">
...
</case> </switch>
I am using the inline javascript prototype feature in the WSO2 API manager and I'm trying to set different HTTP response statuses. Is this possible? If so how is it done?
So far I have tried setting the HTTP_SC property but this doesn't seem to have any effect.
mc.setProperty('HTTP_SC', "404");
I had the same requirement and after much exploring under the hood was able to find a workable solution.
The reason why setting the property:
mc.setProperty('HTTP_SC', "404");
didn't work is that the property needs to be set in the axis2 scope (as Abimaran said). mc.setProperty doesn't set it on that scope. Moreover, the MessageContext object doesn't provide a way to set the scope.
The 'Deploy as Prototype' action actually creates the API definition file by merging the specified in-line script into the a velocity template and storing the resulting API definition into a file.
Template: ./repository/resources/api_templates/prototype_template.xml
Output location: repository/deployment/server/synapse-configs/default/api/
The output file will have a name in the format:
provider--API Name-vVERSION.xml
where provider appears to be the username of the API creator.
What I did was add a filter to the template:
<filter source="boolean(get-property('HTTP_SC'))" regex="false">
<then>
<property name="HTTP_SC" value="200" scope="axis2"/>
</then>
<else>
<property name="HTTP_SC" expression="get-property('HTTP_SC')" scope="axis2"/>
</else>
</filter>
I added it immediately after a similar block (for handling CONTENT_TYPE) at the start of the inSequence element.
You need to add following properties before <send/> mediator
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<property name="HTTP_SC" value="403" scope="axis2"/>
I want to get a URI VAR value from request to call correct case in switch in WSO2 ESB API resource, like this:
<api name="apk" context="/apk"><resource methods="GET" uri-
template="/apk/{appName}"><inSequence><header name="App"
scope="transport" action="remove"/><switch source="get-
property('uri.var.appName')"><case regex="BEBE"><send><endpoint><http
method="GET" uri-template="http://localhost/apk/Bebe.apk></http>
</endpoint></send></case><case regex="CITAS"><send><endpoint><http
method="GET" uri-template="http://localhost/apk/Citas.apk></http>
</endpoint></send></case></switch></inSequence></resource></api>
In switch, source="get-property('uri.var.appName')" it's not correct.
Can I get this value using $url SynapseXpath valiables like $url?
What you have done is correct. Please try the same with a log mediator and see whether you get the value properly.
<log level="custom">
<property name="AppName" expression="get-property('uri.var.appName')"/>
</log>
Alternatively you can assign this to a property and use that inside your switch mediator.
I am building a ReST to ReST proxy service. I need to be able to pass along some query parameters to that service that are incoming with the request. E.g.
myhost.zz/proxyService?foo=1&bar=2
When I define such proxy - and later try to extract the value of 'foo' I get null.
So is it possible to achieve?
You shouls define an API (if you really want a proxy service, look at the end of this answer) :
<api xmlns="http://ws.apache.org/ns/synapse" name="proxyService" context="/proxyService">
<resource methods="POST GET OPTIONS DELETE PUT">
<inSequence>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"></property>
<log level="custom">
<property name="foo" expression="get-property('query.param.foo')"></property>
<property name="bar" expression="get-property('query.param.bar')"></property>
</log>
</inSequence>
</resource>
</api>
call it with this url : http://host:port/proxyService?foo=12&bar=14
look at wso2-esb-service.log : INFO __SynapseService foo = 12, bar = 14
in the "resource", you can define a uri-template (URL Style = uri-template) with, for exemple, "/{scope}/*" and then when you call your api with http://host:port/proxyService/toto?foo=12&bar=14, you can access the "scope" with get-property('uri.var.scope')
to send a REST request, use a http endpoint with a uri-template using the same logic : uri-template="http://other_host:port/Service/{uri.var.scope}/truc?abc={query.param.foo}&dfc={query.param.bar}"
-->
If you want to use a proxy service, you can access to query parameters like this :
request : http://esb:8280/services/MonService?param1=val1¶m2=val2
<property name="PARAM1"
expression="tokenize(substring-after(syn:get-property('To'),'param1='),'&')"
scope="default"
type="STRING"/>
<property name="PARAM2"
expression="tokenize(substring-after(syn:get-property('To'),'param2='),'&')"
scope="default"
type="STRING"/>
you can use synapse xpath variable $url to read the query parameter values.
check this[1] for example.
Reading Dynamic query parameter in WSO2 APIM
I have a sequence that is invoking multiple endpoints. My sequence is:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="GetAllData">
<switch xmlns:ns="http://org.apache.synapse/xsd" xmlns:cct="http://www.tempuri.org" xmlns:tns="http://www.tempuri.org" source="//tns:IDFilter/cct:ID">
<case regex=".?">
<log level="custom">
<property name="Property2" value="----------------Inside switch 1 ? ---------------"/>
</log>
<filter xpath="//tns:ChildIDFilter/cct:ID='?'">
<then>
<log level="custom">
<property name="prop1" value="------Inside Then------------------"/>
</log>
**<payloadFactory>
<format>
<select_all_ID_operation xmlns:cir="http://tempuri.org"/>
</format>
</payloadFactory>
<payloadFactory>
<format>
<select_all_ChildID_operation xmlns="http://tempuri.org"/>
</format>
</payloadFactory>
<send>
<endpoint key="ID_Service_EPS"/>
</send>**
</then>
<else>
<log level="custom">
<property name="prop2" value="------Inside Else------------------"/>
</log>
<payloadFactory>
<format>
<select_all_ID_operation xmlns="http://tempuri.org"/>
</format>
</payloadFactory>
<send receive="ValidateAllData">
<endpoint key="ID_Endpoint"/>
</send>
</else>
</filter>
</case>
</switch>
</sequence>
Now in my ID_EPS endpoint, i have two wsdl endpoints and for them i have to pass payload to get data from both wsdl's, but this is not happenning. My question is how to invoke recipient endpoint contaning different wsdl Endpoints and setting payload for it and finally get the concatinated result. Looking forward to your answers.Thanks in advance
In the management console-->endpoint menu, you can find the recipient list endpoint, where provide your both endpoints, and refer that recipient endpoint from your sequence
To send messages to two endpoints (in your case two wsdl endpoints) using recipient list endpoint, the message format accepted by both endpoints should be identical.
If so, you can send messages to both endpoints using a recipient list endpoint and then aggregate the response messages and construct the concatenated result.
Refer to following resource to find a sample configuration of Recipient list endpoint.
http://docs.wso2.org/wiki/display/ESB460/Sample+62%3A+Routing+a+Message+to+a+Dynamic+List+of+Recipients+and+Aggregating+Responses
If two endpoint message formats are not identical, you have to implement a service chaining scenario or you can clone the message and create two different branches for two endpoints and construct the payload required by each service endpoint and send to the service endpoint within that branch. Then you can aggregate the responses received from both branches and construct the concatenated result.