How to use pattern and group in property mediator to validate - wso2

how to use pattern and group for validating property.
<property name="string" [action=set|remove] [type="string"]
(value="literal" | expression="xpath")
[scope=default|transport|axis2|axis2-client] [pattern="regex"
[group="integer"]]>
</property>

Pattern in Property mediator can be used to match the value or the result of an expression against a given pattern. If the pattern matches, Property mediator returns the value. Else, it returns an empty string.
For example, in the following example, only Test1 property value matches with the pattern. Hence, only Test1 returns the value. Test2 returns an empty string.
<property name="Test1" value="5" scope="default" type="STRING" pattern="[0-9]" group="0"/>
<property name="Test2" value="20" scope="default" type="STRING" pattern="[0-9]" group="0"/>
<log level="custom">
<property name="Test1 Value : " expression="get-property('Test1')"/>
<property name="Test2 Value : " expression="get-property('Test2')"/>
</log>
And, "group" attribute in Property mediator is intended to be used to evaluate against the number of capturing groups in this matcher's pattern, similar to java.util.regex.Matcher.groupCount() in Java. However, apparently the group support is not available in WSO2 EI 6.5.0 at the moment.

Related

How to get json property when I use the Property Mediator?

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.

XSLT: Xpath to count items with attribute value matching another specific sibling

I have the following (simplified; there are more Property-Lines) XML-File that I need to process by XSLT:
<Collection Name="Columns" Type="OutputColumn">
<SubRecord>
<Property Name="Name">SID</Property>
<Property Name="SqlType">BigInt</Property>
<Property Name="Derivation">inputstream1.SID</Property>
<Property Name="Description">Main key</Property>
</SubRecord>
<SubRecord>
<Property Name="Name">name</Property>
<Property Name="SqlType">Char</Property>
<Property Name="Derivation">inputstream2.name</Property>
<Property Name="Description">Surname</Property>
</SubRecord>
<SubRecord>
<Property Name="Name">street</Property>
<Property Name="SqlType">Char</Property>
<Property Name="Derivation">inputstream1.streetname + inputstream1.number</Property>
<Property Name="Description">Full street</Property>
</SubRecord></Collection>
I now need to know two things as a variable in XSLT to decide what to do further in an if-Condition:
Is there at least one SubRecord where substring-after(Derivation, '.') matches the sibling Property "Name" (so like in the first two SubRecords)?
Is there at least one SubRecord where substring-after(Derivation, '.') does not match the sibling Property "Name" (so like in the third SubRecord)?
I tried to do this by Xpath with the Count()-Functionality but simply can't figure out how to do the comparison to the sibling Property node with "Name" as it's name...I'm also open for other ideas if you know an alternative to Count().
I'm not sure I completely understood the issue, so check below and let me know if it's not what you actually want
First can be done with below XPath:
boolean(//SubRecord[substring-after(./Property[#Name="Derivation"]/text(), '.')=./Property[#Name="Name"]/text()])
This should return true because XPath matches first two SubRecord elements.
Using not() should allow to return true because XPath matches third SubRecord element:
boolean(//SubRecord[not(substring-after(./Property[#Name="Derivation"]/text(), '.')=./Property[#Name="Name"]/text())])

Is it possible to extract and/or pass along a query parameter in ESB REST proxy service

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&param2=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

Can we pass parameters to main sequence url in WSO2 ESB?

I am calling main sequence from localhost:8280 .
I want to pass parameters to main sequence like `
localhost:8280 ?book = "math "
Please suggest if this is feasible to pass parameters in main sequence URL or we need to use Rest API for this?
You can extract such parameters like this :
<property name="PARAM1"
expression="tokenize(substring-after(syn:get-property('To'),'param1='),'&')"
scope="default"
type="STRING"/>
<property name="PARAM1"
expression="tokenize(substring-after(syn:get-property('To'),'param2='),'&')"
scope="default"
type="STRING"/>

How to create Property array in wso2 ESB?

I have my request body as:
<tns:InputRequest xmlns:tns="http://tempuri.org/">
<tns:ID>ID_001</tns:ID>
<tns:ID>ID_002</tns:ID>
<tns:Description>Description for ID_001</tns:Description>
<tns:Description>Description for ID_002</tns:Description>
</tns:InputRequest>
and to get the value of ID and Description, i Have created property as:
<property xmlns:tns="http://tempuri.org/" name="ID" expression="//tns:ID" scope="default" type="STRING"/>
<property xmlns:tns="http://tempuri.org/" name="Description" expression="//tns:Description" scope="default" type="STRING"/>
But this gets me only one value. How can i make a property array so that i can store multiple values of ID and description in it and how to retreive from this array property?Looking forward to your reply.Thanks in advance
You should be able to extract those values using XPATH (//node/child::node()) and then set to property.
Below thread will help you to extract required nodes and set to property. You need to set the type as 'OM' to preserve XML as it is.
how to catch an array of nodes to a property