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>
Related
I use the Property Mediator to get a registry resource, it returns me a json string, but how can I get the property in the json string?
my code example:
test-file.json like so
{
"mappings": {
"mapping": {
"ep_1": "http://localhost:8280/services/ep_1",
"ep_2": "http://localhost:8280/services/ep_2",
"ep_3": "http://localhost:8280/services/ep_3"
}
}
}
I do like this:
<property expression="get-property('registry','conf:customresource/test-file.json')" name="JsonContent" scope="default" type="STRING"/>
<property expression="????" name="endpointUrl" />
how to get the property 'ep_1' in the 'endpointUrl' Or is there any other way to get the property 'ep_1'? thx
Try the following.
expression="json-eval($ctx:JsonContent.mappings.mapping.ep_1)"
If above does not work, try this.
expression="$ctx:JsonContent//mappings/mapping/ep_1"
Saving the input JSON to a property:
<property expression="json-eval($)" name="var_in_JSON" scope="default" type="STRING"/>
!!! Don't use dots (.) in the json property name !!!
...
Using data from a saved json property:
<property expression="json-eval($ctx:var_in_JSON.sub_param)" name="sub_param" scope="default" type="STRING"/>
The answer in your case:
<property expression="json-eval($ctx:JsonContent.ep_1)" name="ep_1" scope="default" type="STRING"/>
You can load json file from registry to payload, and make json-eval on payload. It is dirty solution, but it works ;):
<property expression="base64Decode(get-property('registry','conf:customresource/test-file.json'))" name="JsonContent" scope="default" type="STRING"/>
<payloadFactory description="Build Payload Response" media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="$ctx:JsonContent" xmlns:payload="http://ws.apache.org/commons/ns/payload"/>
</args>
</payloadFactory>
<property expression="json-eval($.mappings.mapping.ep_1)" name="endpointUrl" scope="default" type="STRING"/>
Best regards
I have done with this question.You have to use XML content instead of JSON, then set content into a Property Mediator which type filed is OM, and you can use xpath expression to get any value you want in your XML content.
code example
XML content:
<mappings>
<mapping>
<ep_1>http://localhost:8280/services/ep_1</ep_1>
<ep_2>http://localhost:8280/services/ep_2</ep_2>
<ep_3>http://localhost:8280/services/ep_3</ep_3>
</mapping>
</mappings>
<property expression="get-property('registry','conf:customresource/test-file.xml')" name="XmlContent" scope="default" type="OM"/>
<property expression="$ctx:XmlContent/mapping/ep_1" name="endpointUrl" />
After that, the value will been set into the property named endpointUrl.
Last, please note the expression of second Property mediator,you get black value if you do like this $ctx:XmlContent/mappings/mapping/ep_1.Hope its helpful for someone.
I have a JSON array of the following structure.
{"paymentItems": [
{
"amount": "180000",
"code": "28"
},
{
"amount": "396000",
"code": "06"
},
{
"amount": "1460000",
"code": "01"
}
]
}
Am trying to enrich each item in the array list with an additional JSON value.
<foreach expression="//paymentItems" id="1">
<sequence>
<property expression="//paymentItems/amount" name="amount" scope="default" type="STRING"/>
<property expression="//paymentItems" name="body" scope="default" type="STRING"/>
<log>
<property expression="$ctx:amount" name="INIDIVIDUAL_AMOUNT"/>
</log>
<script language="js"><![CDATA[var amount = mc.getProperty('amount'); var naira = amount/100; mc.setProperty("nairaValue", naira);]]></script>
<log>
<property expression="get-property('nairaValue')" name="NAIRA_VAL"/>
</log>
<property expression="get-property('nairaValue')" name="naira" scope="default" type="STRING"/>
<enrich>
<source type="custom" xpath="$ctx:nairaValue"/>
<target action="child" type="body"/>
</enrich>
</sequence>
</foreach>
As you can see I process the value in the foreach and then use the result and try to add to the array item but it throws no errors and does not add the value.
Foreach mediator does the following
first take a clone of the original message
take an iterated element from the original message (using XPath)
Create a new message context by adding the iterated element to the cloned envelope
Do the mediation steps given in the sequence for that new message context
Since for each iteration, we are cloning a new message context (say context2), and the original message context(say context1) is a separate one, we cannot enrich from context2 to context1.
That's the reason for the behaviour you are experiencing.
As a remedy, you can do the iteration itself from the script mediator and alter the message as required.
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>
I have a backend service with multiple operations. (for example,echoInt and echoString). I want to replace input value for both of them with predefined variables(in the inSequence) with PayloadFactory mediator.
How can i define payloadfactory for different operations?
when i define two payloadfactory mediator for each of them, only the last mediator works for it's operation. when i call other opertaion, this error occures:
wso2 namespace mismatch
operation1:
<p:echoString xmlns:p="http://echo.services.core.carbon.wso2.org">
<in>$1</in>
</p:echoString>
operation2:
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in>$1</in>
</p:echoInt>
My inSequense:
<inSequence>
<payloadFactory media-type="xml">
<format>
<p:echoString xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">teststr</in>
</p:echoString>
</format>
<args/>
</payloadFactory>
<payloadFactory media-type="xml">
<format>
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">1111</in>
</p:echoInt>
</format>
<args/>
</payloadFactory>
</inSequence>
with above inSequense, output result for both operations is '1111':
<ns:echoStringResponse xmlns:ns="http://echo.services.core.carbon.wso2.org">
<return>1111</return>
</ns:echoStringResponse>
thanks in advance
The second Payload factory replaces the first.
If you want to use each of them in a different case, you should define them in a Switch mediator.
You can use a property to get the input that defines which case you should use, then use regex to match the property value. Or you could skip the property and enter the expression in the Switch source.
At the end it would look similar to:
<inSequence>
<property expression="/default/expression" name="input_string" scope="default" type="STRING"/>
<switch source="get-property('input_string')">
<case regex="[\w\s]+">
<payloadFactory media-type="xml">
<format>
<p:echoString xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">teststr</in>
</p:echoString>
</format>
<args/>
</payloadFactory>
</case>
<default>
<payloadFactory media-type="xml">
<format>
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in xmlns="">1111</in>
</p:echoInt>
</format>
<args/>
</payloadFactory>
</default>
</switch>
<respond/>
</inSequence>
If you want call two operations in same time, you should use the clone or iterate Mediator, and use the aggregate Mediator in the outsequence.
The reason you use the two payloadFactory, only last one works, is that one request only have one message context, this mean, you only can send one soap message to back end in same time. This mean the last payloadFactory will override the first one.
Clone or iterate Mediator will clone or split one message context to multiple message context, then you can send multiple soap message to back end services. Because of you got multiple message context, then you should use the aggregate Mediator to aggregate these multiple responses into one message context after back end services return the result.
I'm involved in a proxy service development using WSO2.
In my sequence I've saved the initial current message in a property using the following:
<property name="InitialMessage" expression="$body" scope="default" type="STRING"/>
and now I need to rebuild the initial message using the payload factory mediator. Am I right? What are some considerable alternatives?
Could someone show me the right syntax in this case?
yes your method is correct, But I would suggest you to save only the required properties from your incoming message and use them in building the new message. Sample Syntax is given below
<payloadfactory>
<format>
<m:checkpriceresponse xmlns:m="http://services.samples/xsd">
<m:code>$1</m:code>
<m:price>$2</m:price>
</m:checkpriceresponse>
</format>
<args>
<arg expression="//m0:symbol" xmlns:m0="http://services.samples/xsd">
<arg expression="//m0:last" xmlns:m0="http://services.samples/xsd">
</arg></arg></args>
</payloadfactory>
I've solved my problem using the enrich mediator: Here you are how ...
I've saved my initial message in a property InitialMessage in this manner ...
<property name="InitialMessage" expression="$body" scope="default" type="STRING"/>
and after I've used the enrich mediator in this manner
<enrich>
<source type="property" clone="true" property="InitialMessage"/>
<target type="body"/>
</enrich>
It's working ...
I hope this could be useful ...