I defined a sequence which have Switch...Case mediator and check the condition based on RegEx in WSO2. what is wrong in my below definition ? It supposed to execute first case condition. But, log prints always default section of the switch.
Below code sample, when i print PATH_PROP, returns "/rest/api/v1.0/fee" which is my resource path in the URL. I am trying to match, is there word 'fee' in PATH_PROP variable. In my case, it is.. so, i expected go Case 1. i tried RegEx of "fee", ".fee.", "\bfee\b" and etc. None of them work. What is wrong in my definition ?
Your help is appreciated !!
<property expression="get-property('axis2','REST_URL_POSTFIX')"
name="PATH_PROP" scope="default" type="STRING"/>
<switch source="$ctx:PATH_PROP">
<case regex="fee">
<log level="custom">
<property name="CUSTOM_MESSAGE" value="CASE 1 *************"/>
</log>
<header name="To" scope="default" value="https://localhost:9448/am/sample/pizzashack/v1/api/menu"/>
</case>
<case regex=".*application/xml.*">
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
</case>
<default>
<property name="messageType" scope="axis2" type="STRING" value="text/xml"/>
<log level="custom">
<property name="CUSTOM_MESSAGE" value="CASE_DEFAULT *************"/>
</log>
<header name="To" scope="default" value="http://was.apv.local:9080/rpe/rest/api/v1.0/fee?appID=1"/>
</default>
user regex ".*fee.*" to match the word "fee" in the url. if you wan to match "/fee" then ".*/fee.*"
e.g to match "fee" in $ctx:PATH_PROP
<switch source="$ctx:PATH_PROP">
<case regex="*.fee.*">
------------------
</case>
<default>
------
</default>
Related
We have a very simple EI API. We receive an XML payload, we then extract a destination code from the XML document and, based on the destination code, we forward the payload to the appropriate endpoint.
One of our clients have made a spelling mistake in their payload and we want to correct it before we send it to the new endpoint. We want to replace the word 'Principle' with 'Principal'.
How can we replace a string in the request body with another string?
Here is our current implementation:
<inSequence>
<property expression="//MyXML/Destination" name="Destination" scope="default" type="STRING"/>
<log level="custom">
<property expression="//MyXML/Transaction/Destination" name="Destination"/>
</log>
<property action="remove" name="REST_URL_POSTFIX" scope="axis2"/>
<property description="vendorId" expression="concat('gov:/integration/endpoints/myendpoints/', get-property('uri.var.vendorId'), '_EP')" name="vendorId" scope="default" type="STRING"/>
<log category="DEBUG" description="request_log" level="full">
<property expression="get-property('vendorId')" name="Vendor ID"/>
</log>
<log description="request_log" level="custom">
<property expression="get-property('vendorId')" name="Vendor ID"/>
</log>
<send>
<endpoint key-expression="get-property('vendorId')"/>
</send>
</inSequence>
After reading of WSO2 EI References, I still confuse about how use iterators inside a EI sequence.
In my case I have a payload like this....
{
...
"array": [
{"cpf": "12345678911"},
{"cnpj":"12345678912346"}
]
}
So I have to iterate to check if those guys exist using another web services. in order to achieve that flow, I am using the iterate mediator to split the message and then building the logic to make those validations as follows..
The code that implements this image is following:
<iterate description="" expression="//jsonObject/array" id="myid">
<target>
<sequence>
<property expression="json-eval($.array.cpf)" name="tipoCPF" scope="default" type="STRING"/>
<filter description="" xpath="boolean(get-property('tipoCPF'))">
<then>
<property expression="json-eval($.array.cpf)" name="uri.var.cpf" scope="default" type="STRING"/>
<call>
<endpoint>
<http method="get" uri-template="http://endpoint/service/{uri.var.cpf}"/>
</endpoint>
</call>
<filter regex="200" source="get-property('axis2','HTTP_SC')">
<then/>
<else>
<payloadFactory description="" media-type="json">
<format>{
"code":"400",
"error":"CPF inexistente"
}</format>
<args/>
</payloadFactory>
<property name="HTTP_SC" scope="axis2" type="STRING" value="400"/>
<respond/>
</else>
</filter>
</then>
<else>
<property expression="json-eval($.array.cnpj)" name="tipoCNPJ" scope="default" type="STRING"/>
<filter xpath="boolean(get-property('tipoCNPJ'))">
<then>
<property expression="json-eval($.array.cnpj)" name="uri.var.cnpj" scope="default" type="STRING"/>
<header name="Authorization" scope="transport" value="Basic Y29yZS5jb25zdWx0aW5nOm8xNXRyZWI="/>
<call>
<endpoint>
<http method="get" uri-template="http://endpoint/service/cnpj/{uri.var.cnpj}"/>
</endpoint>
</call>
<filter regex="200" source="get-property('axis2','HTTP_SC')">
<then/>
<else>
<payloadFactory media-type="json">
<format>{
"code":"400",
"error":"CNPJ inexistente"
}</format>
<args/>
</payloadFactory>
<property name="HTTP_SC" scope="axis2" type="STRING" value="400"/>
<respond/>
</else>
</filter>
</then>
<else>
<call>
<endpoint>
<http method="get" uri-template="http://endpoint/service/info"/>
</endpoint>
</call>
</else>
</filter>
</else>
</filter>
</sequence>
</target>
</iterate>
This iterator work as part inside of the an 'insequence'. The 'Insequence' is deigned to allow to insert new contracts information inside the Database.
Problem: after add this iterator, the service starts to make duplicated insertions inside Database. It´s looks like the iteration don´t finish in the edge of tags 'iterator'. It´s like the iteration continues to the rest of insequence.
Try: In order to solve this problem i try to add an aggregator mediator after the iterator. But or doesn't have any effect end the duplicated insert persist, or I receive an error message.
So What is the correct whey to make this iterations inside WSO2 EI?
As you have mentioned, Iteration will occur even outside the iterate tag, until the Aggregate mediator is used. To resolve this issue, you need to add the aggregate mediator inside the iterate mediator. This will stop the iteration within the iterator tag itself.
For your use case, you may need to set continueParent="true" in the IterateMediator, so that the mediation will continue after the iterate mediator for the insertion Operation in database.
Thanks for the helping Arunan!
After your answer I try to add the Aggregator as follows
The config of aggregator is following:
...
<aggregate id="NIRO">
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete expression="//jsonObject">
<log description="" level="full" separator=";">
<property expression="json-eval($.)" name="jsonObject"/>
</log>
</onComplete>
</aggregate>
</sequence>
</target>
</iterate>
As you sad I change the iterator property 'Continue Parent' to 'true'. But the problem persists....
As proposed in the other answer, you need to
use an Aggregate mediator to close the iteration
If and only if the Iterator is set to continueParent="true"
However, I am not sure that putting it inside the <iterate> works. Here is a working solution using an Aggregate mediator right after your Iterator.
<sequence>
<iterate continueParent="true" description="" expression="//jsonObject/array" id="myid">
<target>
<your_sequence />
</target>
</iterate>
<aggregate>
<completeCondition>
<messageCount max="-1" min="-1" />
</completeCondition>
<onComplete enclosingElementProperty="//jsonObject/array" expression="/whatever/you/want"/>
</aggregate>
</sequence>
Notice expression="//jsonObject/array" you used in your Iteration, you'll need to use it in the Aggregator's enclosingElementProperty. This is how your EI will know from which iterator it should aggregate from (not 100% sure about this point, more of an empirical consideration).
We have developed a Project in Developer Studio everything is working fine and our Custom log is creating Custom messages in Carbon log. Our requirement is that our custom log should write in a separate file like 'Interfacing Exceptions Report' so that user can easily track the error instead of reviewing the whole Carbon log because it has too much contents as well.
Currently we have source as follows for custom log:
<property xmlns:ns11="http://xmlns.oracle.com/apps/scm/doo/decomposition/receiveTransform/receiveSalesOrder/model/"
name="OrderNumber"
expression="//ns11:OrderNumber"
scope="default"
type="STRING"/>
<property xmlns:ns11="http://xmlns.oracle.com/apps/scm/doo/decomposition/receiveTransform/receiveSalesOrder/model/"
name="OrderStatus"
expression="//ns11:OrderStatus"
scope="default"
type="STRING"/>
<property xmlns:ns11="http://xmlns.oracle.com/apps/scm/doo/decomposition/receiveTransform/receiveSalesOrder/model/"
name="ReturnStatus"
expression="//ns11:ReturnStatus"
scope="default"
type="STRING"/>
<log level="custom">
<property name="prop1" expression="get-property('OrderNumber')"/>
<property name="prop2" expression="get-property('OrderStatus')"/>
</log>
<filter source="get-property('ReturnStatus')" regex="SUCCESS">
<then>
<log level="custom">
<property name="message" value="Your order has been created successfully "/>
</log>
</then>
<else>
<log level="custom">
<property name="errormessage" value="Sorry,there was an issue in order creation"/>
</log>
</else>
</filter>
What you're looking for sounds like per service logging or per api logging.
I have a sequence as part of proxy service which filters based on "Source and Regular Expression". I have defined source as element value coming as part of SOAP request and regular expression as "local entry defined in ESB". However, result is not what I am expecting.
Local Entry is defined as Inline Text (myFields) - FIELD1|FIELD2|FIELD3
Mediation sequence is defined as -
<sequence xmlns="http://ws.apache.org/ns/synapse" name="007">
<property xmlns:ns="http://org.apache.synapse/xsd" name="fieldName" expression="$body/fieldName/text()" scope="default" type="STRING"/>
<filter xmlns:ns="http://org.apache.synapse/xsd" source="get-property('fieldName')" regex="get-property('myFields')">
<then>
<log level="full" separator="*****YES*********">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</then>
<else>
<log level="full" separator="*********NO**************">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</else>
</filter>
</sequence>
When I am sending SOAP request as -
<body>
<fieldName>FIELD1</fieldName>
</body>
execution is always going to else part. Any suggestion ?
With filter mediator, regex attribute must be a string, not an expression.
You can use XPATH2 "matches"
Sample :
<inSequence>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="fieldName" expression="$body/fieldName/text()"/>
<property xmlns:fn="http://www.w3.org/2005/xpath-functions" name="match" expression="fn:matches(syn:get-property('fieldName'),syn:get-property('myFields'))"/>
<filter source="get-property('match')" regex="true">
<then>
<log level="full" separator="*****YES*********">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</then>
<else>
<log level="full" separator="*********NO**************">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</else>
</filter>
<log level="full"/>
</inSequence>
Here is my proxy code:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="ProviderPublication" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<filter xmlns:p="http://www.openoandm.org/xml/ISBM/" xpath="//p:OpenPublicationSession">
<then>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="ChannelURI" expression="//xs:ChannelURI" scope="default" type="STRING"/>
<class name="wso2.org.Communicator.OpenPublication">
<property name="channelURI" value="myChannelURI"/>
</class>
**<property name="sessionIDFromClassMediator" expression="get-property('SessionID')" scope="default" type="STRING"/>**
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<payloadFactory>
<format>
<ns1:OpenPublicationSessionResponse xmlns:ns1="http://www.openoandm.org/xml/ISBM/">
<ns1:SessionID>$1</ns1:SessionID>
</ns1:OpenPublicationSessionResponse>
</format>
<args>
<arg expression="get-property('sessionIDFromClassMediator')"/>
</args>
</payloadFactory>
<send/>
</then>
<else>
<filter xpath="//p:PostPublication">
<then>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="SessionID" expression="//xs:SessionID" scope="default" type="STRING"/>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="Topic" expression="//xs:Topic" scope="default" type="STRING"/>
<property xmlns:xs="http://www.openoandm.org/xml/ISBM/" name="Expiry" expression="//xs:Expiry" scope="default" type="STRING"/>
<property xmlns:ns="http://www.openoandm.org/xml/ISBM/" name="MessageContent" expression="//MessageContent" scope="default" type="STRING"/>
<class name="wso2.org.postPublication.PostPublication">
<property name="topic" value="Sports"/>
<property name="sessionID" value="session_001"/>
<property name="messagecontent" value="Cricket on air"/>
<property name="expiry" value="Monday"/>
</class>
<property name="getMessageIDFromClassMed" expression="get-property('MessageID')" scope="default" type="STRING"/>
<log level="full">
**<property name="SessionIDFromFstFltr" expression="get-property('sessionIDFromClassMediator')"/>**
</log>
I AM NOT ABLE TO GET THE PROPERTY VALUE OF sessionIDFromClassMediator SO MY FILTER NEVER GETS TRUE AND CAN'T GET INSIDE THE FILTER
**<filter xpath="get-property('sessionIDFromClassMediator') = get-property('SessionID')">
<then>
<log level="custom">
<property name="STATE" value="message is sent to queue"/>
</log>
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<payloadFactory>
<format>
<ns1:PostPublicationResponse xmlns:ns1="http://www.openoandm.org/xml/ISBM/">
<ns1:MessageID>$1</ns1:MessageID>
</ns1:PostPublicationResponse>
</format>
<args>
<arg expression="get-property('getMessageIDFromClassMed')"/>
</args>
</payloadFactory>
<send/>
</then>
<else>
<log level="full">
<property name="FilterNotRunning" value="----------FilterNotRunning------------------"/>
</log>
<drop/>
</else>
</filter>**
</then>
<else>
<drop/>
</else>
</filter>
</else>
</filter>
</inSequence>
<endpoint>
<address uri="jms:/myQueue?&transport.jms.DestinationType=queue"/>
</endpoint>
So i want to get the value of <property name="sessionIDFromClassMediator" expression="get-property('SessionID')" scope="default" type="STRING"/> so that i can use this property value to match with Other Property after
<class name="wso2.org.postPublication.PostPublication">
<property name="topic" value="Sports"/>
<property name="sessionID" value="session_001"/>
<property name="messagecontent" value="Cricket on air"/>
<property name="expiry" value="Monday"/>
</class>
and after that i am sending message to Message broker but before that i want to associate a payload which should be send to the queue of message broker. I want to implement payload inside
I AM NOT ABLE TO GET THE PROPERTY VALUE OF sessionIDFromClassMediator SO MY FILTER NEVER GETS TRUE AND CAN'T GET INSIDE THE FILTER
**<filter xpath="get-property('sessionIDFromClassMediator') = get-property('SessionID')">
<then>
<log level="custom">
<property name="STATE" value="message is sent to queue"/>
</log>
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<payloadFactory>
<format>
<ns1:PostPublicationResponse xmlns:ns1="http://www.openoandm.org/xml/ISBM/">
<ns1:MessageID>$1</ns1:MessageID>
</ns1:PostPublicationResponse>
</format>
<args>
<arg expression="get-property('getMessageIDFromClassMed')"/>
</args>
</payloadFactory>
<send/>
</then>
<else>
<log level="full">
<property name="FilterNotRunning" value="----------FilterNotRunning------------------"/>
</log>
<drop/>
</else>
</filter>**
part.THE MAIN PROBLEM IS THAT THE FIRST FILTER IS EXECUTED WHEN I ENVOKE OPERATION OPENPUBLICATION, AND WHEN I ENVOKE THE SECOND OPERATION ALL THE PROPERTY VALUE GET RESET. SO HOW CAN I MAKE PROPERTY VALUE PERSISTENT SO THAT IT IS NEVER LOST? Hope you understand my question and looking forward to your solutions. Thanks in advance
Try to add some logs of your property to see if it is there or not:
<log level="custom">
<property name="your property" expression="get-property('sessionIDFromClassMediator'))"/>
</log>
Keep in mind the different levels of the properties (transport, axis2, axis2-client).
I also had quite some problems with the filter mediator using the xpath attribute. I don't use it anymore and always use the combination of "source" and "regex".
Example:
<filter source="$body/anElementInTheBody" regex="true">
So for your case you can create an additional property (just before the filter) that will contain the boolean value if it should be filtered or not. Then with the regex=true you will enter the filter.
This is just a pseudo code of your example - maybe need some corrections:
<property name="filterCondition" expression="get-property('sessionIDFromClassMediator') = get-property('SessionID')"/>
<filter source="get-property('filterCondition')" regex="true">