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'))}"/>
Related
I am working with the WSO2 ESB 6.5.0 and am using the fileconnector-2.0.21 version for file operations. The proxy service that I'm building is intended to read the files from a certain source path and merge the contents into a file at the destination path.
The content of the proxy service artifact is below
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="FileMergeProxy" startOnLoad="true" transports="http https" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log description="Combine files" level="custom" separator="| ">
<property name="statusMessage" value="Processing complete"/>
<property name="fileCreation" value="Initiating file merge"/>
<property expression="$ctx:mergeDirPath" name="sourceDir"/>
<property expression="$ctx:finalDirPath" name="destDir"/>
<property expression="$ctx:outputFilePattern" name="pattern"/>
<property expression="fn:concat('file:///', $ctx:mergeDirPath)" name="sourceDir1" scope="default" type="STRING"/>
property expression="fn:concat('file:///', $ctx:finalDirPath)" name="destDir1" scope="default" type="STRING"/>
</log>
<fileconnector.mergeFiles>
<source>{$ctx:mergeDirPath}</source>
<destination>{$ctx:finalDirPath}</destination>
<filePattern>{$ctx:outputFilePattern}</filePattern>
</fileconnector.mergeFiles>
<log description="Processing complete" level="custom" separator="| ">
<property name="doneMessage" value="File merge processing complete"/>
</log>
</inSequence>
<outSequence/>
<faultSequence>
<log level="custom">
<property name="text" value="An unexpected error occured"/>
<property expression="get-property('ERROR_MESSAGE')" name="message"/>
<property expression="get-property('ERROR_DETAIL')" name="errordetail"/>
</log>
<send description="Send Error Information"/>
</faultSequence>
</target>
</proxy>
I'm invoking the service with the following parameters as a JSON file
{
"mergeDirPath": "C://temp//merge//",
"finalDirPath": "C://temp//final//finalcontent.txt",
"outputFilePattern": "\\*txt"
}
When I call the service after deploying the artifacts to the ESB engine, it creates an empty file in the destination path without merging the contents of the files in the source directory. This is the extract from the WSO2 logs.
[2020-03-23 12:48:36,683] [] INFO - LogMediator To: /services/FileMergeProxy,MessageID: urn:uuid:b569ec6a-d4fe-4763-a0ca-fb2eb868a31e correlation_id : a1c542bb-7fac-4e0b-9582-8cb1a605f618,Direction: request,Payload: { "mergeDirPath": "C://temp//merge//", "finalDirPath": "C://temp//final//finalcontent.txt", "outputFilePattern": "\\*txt" }
[2020-03-23 12:49:00,422] [] INFO - LogMediator statusMessage = Combine files| fileCreation = Initiating file merge| sourceDir = C://temp//merge//| destDir = C://temp//final//finalcontent.txt| pattern = \*txt| sourceDir1 = file:///C://temp//merge//| destDir1 = file:///C://temp//final//finalcontent.txt
[2020-03-23 12:49:02,943] [] INFO - LogMediator doneMessage = File merge processing complete
Unless I'm missing something here, shouldn't the mergeFiles be doing exactly that - merge the contents of files in a specified directory ? Any helpful suggestions or pointers are welcome. Thanks in advance.
According to the proxy you have shared, you have defined properties inside the log mediator. Define the properties outside the log mediator.
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
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>
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
I have a text file on my local system I wish to append the data in particular file as synchronously.
I have tried many ways, but it's not working.
ESB has this future in Oracle SOA. We can add in FILE ADAPTER. In ESB it's neither giving errors nor expected result.
My configuration is like this:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="FileWrite" transports="http,vfs" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<log>
<property name="OUT_ONLY" value="true"/>
</log>
</inSequence>
<outSequence>
<log>
<property name="OUT_ONLY" value="true"/>
</log>
<payloadFactory>
<format>
<error>error404</error>
</format>
</payloadFactory>
<send>
<endpoint>
<address uri="vfs:file:///home/youtility2/Desktop/Errorlog"/>
</endpoint>
</send>
</outSequence>
</target>
<parameter name="transport.vfs.ReplyFileURI">file:///home/user/test/out? transport.vfs.Append=true</parameter>
<parameter name="transport.PollInterval">10</parameter>
<parameter name="transport.vfs.FileNamePattern">Errorlog.text</parameter>
<parameter name="transport.vfs.ContentType">text/xml</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<parameter name="transport.vfs.ReplyFileName">Errorlog.xml</parameter>
<description></description>
</proxy>
Actually I kept a log mediator in outSequence. The inSequence mediator is not sending the data in to the outSequence process not forwarding into outSequence. That's why I think that the above configuration is not working.
Any reference for this?
I tried above configuration in inSequence also. It's giving errors like this:
ERROR - Axis2Sender Unexpected error during sending message out
org.apache.axis2.AxisFault:
The VFS transport doesn't support synchronous responses. Please use
the appropriate (out only) message exchange pattern
Please refer to this link.
The issue is, you are setting a property inside a log mediator which is a predefined property, (ie:OUT_ONLY) which is used to indicate the request is only the "out-only" request. So, system, wont expect the response back. That is why, you are not getting anything in your outsequence.
DO NOT USE the predefined properties in the Log mediator,which will cause issues.
Keep some text in the log meditaor to indictae the flow of the message.
eg:
<inSequence>
<log>
<property name="INSEQUENCEEEEEEE" value="********"/>
</log>
</inSequence>
Like wise keep different descriptive log in the outsequence and see whether you are getting the message there, without any issue.