tokenize function is not reading the value from property in wso2 - wso2

I need to use tokenize function in my wso2 sequence file.
I am getting the username like testuser#gmail. I need to split the string using the delimeter #. I am using the below code.
. But, It is always printing blank in logs.
Could you please some one help me.
PS:: I have enabled xslt2.0 in my synapse.properties file.

Use the substring-before function
<property name="tokentest" value="testuser#gmail" scope="default" type="STRING"/>
<property name="NEW_CONTENT_TYPE" expression="substring-before($ctx:tokentest,'#')" scope="default" type="STRING"/>
<log level="custom">
<property name="NEW_CONTENT" expression="$ctx:NEW_CONTENT_TYPE"/>
</log>
Hope this helps

Related

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

Custom Policies API Manager

I tried to create a custom policy, with a purpose a mask of service:
Original Services in API:
http://API/v1/profile
http://API/v1/account
With mask:
http://API/v1/user-profile
http://API/v1/user-account
And combination the answer of User Bee this a solution for this problem:
<switch source="get-property('axis2', 'REST_URL_POSTFIX')">
<case regex="/v1/kyc-profile">
<property name="REST_URL_POSTFIX" value="/v1/profile" scope="axis2"/>
</case>
<case regex="/v1/kyc-account">
<property name="REST_URL_POSTFIX" value="/v1/account" scope="axis2"/>
</case>
</switch>
But this solution only works where the services is static, but I have others services, similar to:
http://API/v1/user-profile/{id-user}/details
http://API/v1/user-profile/{id-user}?expand=some_information
For the last service I have this:
<switch source="get-property('axis2', 'REST_URL_POSTFIX')">
<case regex="v1/user-profile/[\/\w\W]*">
<property name="REST_URL_POSTFIX" value="/v2/cliente/{id-user}?expand=some_information" scope="axis2"/>
</case>
</switch>
[/\w\W]* This part is regular expression for {id-user}?expand=some_information and similar.
The problem is: I need put dynamic value because the property value (<property name="REST_URL_POSTFIX" value="THIS" scope="axis2"/>) takes this text, example:
Service before to policie
http://API/v1/user-profile/1?expand=some_information
Service after to policie
http://API/v1/user-profile/{id-user}?expand=some_information
My questions are:
How to put a dynamic value for the services similar to: http://API/v1/user-profile/{id-user}?expand=some_information?
For the other service, http://API/v1/user-profile/{id-user}/details I have the similar situacion, How a resolve?
In your mediation sequence, try changing the backend URL as follows.
http://API/v1/user-profile/{uri.var.id-user}?expand=some_information
Example:
<switch source="get-property('axis2', 'REST_URL_POSTFIX')">
<case regex="v1/user-profile/[\/\w\W]*">
<property name="REST_URL_POSTFIX" value="/v2/cliente/{uri.var.id-user}?expand=some_information" scope="axis2"/>
</case>
</switch>

How can I get port number of sender service in wso2?

This is my first question, so see my effor and answer my question :)
I need to get address of server, so I got server IP with this property
<property expression="get-property('SERVER_IP')" name="StringServerIp" scope="default" type="STRING"/>
I tried this property to get the port number ,and it returns null <property expression="get-property('system.port.no')" name="system.port.no"/>
Please help me to get port number of sender
any idea or any refering are appreciated
Try this.
<script language="js">mc.setProperty("port",java.lang.System.getProperty("xxxx"));</script>
<log level="custom">
<property name="port" expression="get-property('port')"/>
</log>
Here xxxx can be one of below.
mgt.transport.http.port
mgt.transport.https.port
http.nio.port
https.nio.port

WSO2 ESB, and different response types for the same call

I am using WSO2 4.9.
I have a simple endpoint defined as such
<endpoint name="someEndpoint">
<address uri="someAddress" format="soap11">
</endpoint>
This specific endpoint also requires basic HTTP auth, which I provide like this:
<property name="Authorization" description="Set-User-Pwd" expression="fn:concat('Basic ', $ctx:authorizationProperty)" scope="transport" type="STRING"/>
I make a simple call towards it like this:
<call description="Some description">
<endpoint key="someEndpoint"/>
</call>
I should note that the server which I'm attempting to call:
responds with a SOAP answer (i.e. proper XML, etc) when all is good
responds with a HTML answer when authorization errors happen
The problem I'm having concerns the situation when I'm passing it a wrong user. I'm expecting that in this scenario, my fault sequence would get invoked (the above is part of an api declaration, which also has a fault sequence).
But this doesn't happen, and I get the following error:
Caused by: com.ctc.wstx.exc.WstxParsingException: Unexpected close tag </body>; expected </HR>.
at [row,col {unknown-source}]: [1,1054]
I suspect this is happening because WSO2 attempts to parse my HTML response as if it were XML, and fails (which is understandable). I also suspect that this happens before any error sequence gets invoked, etc, and hence my problem.
Edit1: At the beginning of my outSequence, I have a log line which isn't getting printed. So I don't think this is something caused by whatever mediators are in outSequence.
<outSequence>
<log level="custom">
<property name="message" value="OUT call!!!!!!!!!!!!!!!!!!!!!!!" />
</log>
...
</outSequence>
Edit2: Some more details about inSequence.
It contains these lines, which seem to make no difference on the error message (i.e. I get the same if I remove).
<property name="messageType" scope="axis2" value="application/xml"/>
<property name="ContentType" scope="axis2" value="application/xml"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove" />
What can I do in this situation in order to be able to catch these errors? I should note that I don't particularly care about the text in the body (I'm only interested in HTTP status code and maybe HTTP status message).

wso2 - using value from a property to retrive sequence name

I'm configuring a proxy-service and I have three sequences: s1,s2,s3
The value of 1,2,3 is stored in a local registry variable and it's get from the registry and stored in the property called 'myProp'
now, based on the value of this myProp I would like to call one of the three sequences.
I tried this:
<sequence key="s{concat(get-property('myProp'))}"/>
but doesn't works.
This is the property code:
<property name="myProp"
expression="get-property('registry','conf:repository/myVersion2.xml')"
scope="default"
type="STRING"/>
and this is what I'm trying to do:
<filter source="get-property('myProp')"
regex=".*>1<.*"
description="filter">
<then>
<log level="custom" separator=":">
<property name="TestVersion" value="LOG_S1_TRUE"/>
<property name="TestVersion" expression="get-property('myProp')"/>
</log>
<sequence key="s{concat(get-property('myProp'))}"/>
</then>
<else>
<log level="custom" separator=":">
<property name="TestVersion" value="LOG_S1_FALSE"/>
</log>
</else>
</filter>
I get this error from the log:
TID: [0] [ESB] [2015-07-03 12:47:25,340] ERROR {org.apache.synapse.mediators.base.SequenceMediator} - Sequence named Value {name ='null', keyValue ='s{concat(get-property('myProp'))}'} cannot be found {org.apache.synapse.mediators.base.SequenceMediator}
Thanks in advance to who know how to solve it.
Regards
Claudio
Assign the keyvalue to a property first to test it, you will notice that it cannot work :)
Try:
<sequence key="{concat('s', get-property('myProp'))}"/>