I am trying to implement a sequence template that calls a endpoint template leveraging the parameters.
My code is as follows:
SEQUENCE-
<sequence xmlns="http://ws.apache.org/ns/synapse" name="aFileWriteSequence" trace="disable">
<log level="custom">
<property name="sequence" value="aFileWriteSequence"></property>
</log>
<property xmlns:ns="http://org.apache.synapse/xsd" name="filename" expression="get-property('transport', 'FILE_NAME')" scope="default" type="STRING"></property>
<call-template target="FileWriteTemplate">
<with-param name="targetFileName" value="A_TITLE"></with-param>
<with-param name="addressUri" value="vfs:file:///var/process/ren/rrout"></with-param>
</call-template>
</sequence>
SEQUENCE TEMPLATE-
<template xmlns="http://ws.apache.org/ns/synapse" name="FileWriteTemplate">
<parameter name="targetFileName"></parameter>
<parameter name="addressUri"></parameter>
<sequence>
<log level="custom">
<property xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" name="TARGET_FILE_NAME" expression="$func:targetFileName"></property>
<property xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" name="ADDRESS_URI" expression="$func:addressUri"></property>
</log>
<property xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" name="transport.vfs.ReplyFileName" expression="fn:concat($func:targetFileName, '-', get-property('SYSTEM_DATE', 'yyMMddHHmmss') , '.xml')" scope="transport" type="STRING"></property>
<property name="OUT_ONLY" value="true"></property>
<send>
<endpoint name="ep" template="FileOutEndpointTemplate" uri="$func:addressUri">
<axis2ns117:parameter xmlns:axis2ns117="http://ws.apache.org/ns/synapse" name="retries" value="3"></axis2ns117:parameter>
<axis2ns118:parameter xmlns:axis2ns118="http://ws.apache.org/ns/synapse" name="codes" value="1001"></axis2ns118:parameter>
<axis2ns119:parameter xmlns:axis2ns119="http://ws.apache.org/ns/synapse" name="factor" value="1.0"></axis2ns119:parameter>
</endpoint>
</send>
</sequence>
</template>
ENDPOINT TEMPLATE-
<template xmlns="http://ws.apache.org/ns/synapse" name="FileOutEndpointTemplate">
<axis2ns131:parameter xmlns:axis2ns131="http://ws.apache.org/ns/synapse" name="codes"></axis2ns131:parameter>
<axis2ns132:parameter xmlns:axis2ns132="http://ws.apache.org/ns/synapse" name="factor"></axis2ns132:parameter>
<axis2ns133:parameter xmlns:axis2ns133="http://ws.apache.org/ns/synapse" name="retries"></axis2ns133:parameter>
<endpoint name="$name">
<address uri="$uri">
<suspendOnFailure>
<errorCodes>$codes</errorCodes>
<progressionFactor>$factor</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>$retries</retriesBeforeSuspension>
<retryDelay>0</retryDelay>
</markForSuspension>
</address>
</endpoint>
</template>
I have tried several variations on the $Uri in particular and I cannot get it to work. Essentially, here is the error I am getting:
2015-09-17 16:23:31,026 [-] [SynapseWorker-19] ERROR ClientUtils The system cannot infer the transport information from the $func:addressUri URL.
2015-09-17 16:23:31,026 [-] [SynapseWorker-19] ERROR Axis2Sender Unexpected error during sending message out
org.apache.axis2.AxisFault: The system cannot infer the transport information from the $func:addressUri URL.
I would appreciate any recommendation anyone would have to configure this line:
<endpoint name="ep" template="FileOutEndpointTemplate" uri="$func:addressUri">
Especially how to code the parameter addressUri being passed in from the sequence template call in my sequence.
Address endpoint doesn't support dynamic endpoints. So you can't pass a dynamic value ($func:addressUri is dynamic) to uri parameter of template endpoint. Hence if you want to have a dynamic endpoint, then you can use a default endpoint together with a "To" header which you can set dynamically. Here is the changes to your artifacts.
No changes to your sequence
Set To header using header mediator in your sequence template just before the send mediator, as shown below.
<template xmlns="http://ws.apache.org/ns/synapse" name="FileWriteTemplate">
<parameter name="targetFileName"></parameter>
<parameter name="addressUri"></parameter>
<sequence>
<log level="custom">
<property xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" name="TARGET_FILE_NAME" expression="$func:targetFileName"></property>
<property xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" name="ADDRESS_URI" expression="$func:addressUri"></property>
</log>
<property xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" name="transport.vfs.ReplyFileName" expression="fn:concat($func:targetFileName, '-', get-property('SYSTEM_DATE', 'yyMMddHHmmss') , '.xml')" scope="transport" type="STRING"></property>
<property name="OUT_ONLY" value="true"></property>
<header name="To" expression="$func:addressUri"/>
<send>
<endpoint name="ep" template="FileOutEndpointTemplate">
<axis2ns117:parameter xmlns:axis2ns117="http://ws.apache.org/ns/synapse" name="retries" value="3"></axis2ns117:parameter>
<axis2ns118:parameter xmlns:axis2ns118="http://ws.apache.org/ns/synapse" name="codes" value="1001"></axis2ns118:parameter>
<axis2ns119:parameter xmlns:axis2ns119="http://ws.apache.org/ns/synapse" name="factor" value="1.0"></axis2ns119:parameter>
</endpoint>
</send>
</sequence>
</template>
Change address endpoint to default endpoint in your endpoint template, as shown below
<template xmlns="http://ws.apache.org/ns/synapse" name="FileOutEndpointTemplate">
<axis2ns131:parameter xmlns:axis2ns131="http://ws.apache.org/ns/synapse" name="codes"></axis2ns131:parameter>
<axis2ns132:parameter xmlns:axis2ns132="http://ws.apache.org/ns/synapse" name="factor"></axis2ns132:parameter>
<axis2ns133:parameter xmlns:axis2ns133="http://ws.apache.org/ns/synapse" name="retries"></axis2ns133:parameter>
<endpoint name="$name">
<default>
<suspendOnFailure>
<errorCodes>$codes</errorCodes>
<progressionFactor>$factor</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>$retries</retriesBeforeSuspension>
<retryDelay>0</retryDelay>
</markForSuspension>
</default>
</endpoint>
</template>
The idea behind this solution is that you can set To header dynamically and the default endpoint will send the messages out to the endpoint found in "To" header.
Refer this for more details.
1
Related
I have created a API in API manager. I can invoke it with
http://localhost:6547/generatereports/1.0/Reports/dcuid/vcid
I am passing two parameters with "dcuid and vcid" at a time but not passing.
reportsapi:
<?xml version="1.0" encoding="UTF-8"?>
<api context="generatereports/1.0/Reports" name="reportsdataapi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" uri-template="/{dcuid}/{vcid}">
<inSequence>
<property description="http" name="HTTP_SC" scope="axis2" type="STRING" value="404"/>
<log level="full"/>
<send>
<endpoint key="reportsendpoint"/>
</send>
</inSequence>
<outSequence>
<switch source="get-property('axis2','HTTP_SC')">
<case regex="200">
<log description="200log" level="custom">
<property expression="$ctx:ERROR_CODE" name="200reserrorcode"/>
</log>
<send/>
</case>
<default>
<log description="reslog" level="custom">
<property expression="$ctx:ERROR_CODE" name="reserrorcode"/>
<property expression="$ctx:ERROR_MESSAGE" name="reserrormessage"/>
<property expression="get-property('axis2','HTTP_SC')" name="reshttpsc"/>
</log>
</default>
</switch>
<send/>
</outSequence>
<faultSequence>
<switch source="get-property('axis2','HTTP_SC')">
<case regex="200">
<log description="200log" level="custom">
<property expression="$ctx:ERROR_CODE" name="200reserrorcode"/>
</log>
</case>
<default>
<log description="reslog" level="custom">
<property expression="$ctx:ERROR_CODE" name="reserrorcode"/>
<property expression="$ctx:ERROR_MESSAGE" name="reserrormessage"/>
<property expression="get-property('axis2','HTTP_SC')" name="reshttpsc"/>
</log>
</default>
</switch>
<send/>
</faultSequence>
</resource>
</api>
wso2 configuration process with to send the response is other than 200 response code
reportsendpoint:
<?xml version="1.0" encoding="UTF-8"?>
<endpoint name="reporsendpoint" xmlns="http://ws.apache.org/ns/synapse">
<http method="get" uri-template="http://localhost:6547/generatereports/1.0/Reports/{uri.var.dcuid}/{uri.var.vcid}"/>
</endpoint>
I assume you want to send a mail if the status code is other than 200. Then you can use mailto transport or mail connectors such as gmail connector outlook connector and add the configuration in the default section in the configured switch mediator.
<?xml version="1.0" encoding="UTF-8"?>
<sequence name=SEQUENCE trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<iterate expression=EXPRESSION sequential="true" xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<log level="full">
<property expression="$body/*" name="Test within iterate"/>
</log>
<call>
<endpoint>
<http method="POST" uri-template=URI TEMPLATE
</endpoint>
</call>
<log>
<property name="After CALL" value="response"/>
</log>
</sequence>
</target>
</iterate>
<aggregate>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete expression="$body/*" sequence="OutSequenceforData"
xmlns:ns="http://org.apache.synapse/xsd"
xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s12="http://www.w3.org/2003/05/soap-envelope"/>
</aggregate>
<send/>
<log level="full">
<property expression="$body/*" name="After Aggregate" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
</sequence>
I am trying to invoke a web service using call mediator. But I do not see any log about the call in the wso2 logs. The goal is to display the data from a file in the web service.
Yes you can, after the Call mediator put a Log mediator.
<log level="full" xmlns="http://ws.apache.org/ns/synapse"/>
My goal is to put messages that return a soap error on a queue, in order to retry them later.
I have nearly all working, but the most important part : I can't access the original message from the fault sequence of my proxy :(
I first made a proxy service that returns an error for a given value, or OK for the other values :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestProxyService" transports="http https" startOnLoad="true" trace="disable">
<target>
<inSequence>
<log level="custom">
<property name="TestProxyService" value="InSequence"/>
</log>
<switch xmlns:bnc="http://bnc.org/" source="//bnc:id">
<case regex="1">
<log level="custom">
<property name="TestProxyService" value="Send Error !"/>
</log>
<makefault version="soap11">
<code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:VersionMismatch"/>
<reason value="ERROR ERROR ERROR"/>
<detail>ERROR</detail>
</makefault>
<respond/>
</case>
<default>
<log level="custom">
<property name="TestProxyService" value="No Error"/>
</log>
<log level="custom">
<property name="id" expression="//bnc:id"/>
</log>
<payloadFactory media-type="xml">
<format>
<bnc:response>OK</bnc:response>
</format>
<args/>
</payloadFactory>
<respond/>
</default>
</switch>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
</proxy>
And it works fine
I then made another proxy, that uses the first one as an endpoint to test the queuing on error :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="QueuingProxyService" transports="https http" startOnLoad="true" trace="disable">
<target>
<inSequence>
<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true" scope="default" type="STRING"/>
<send>
<endpoint key="TestProxyServiceEndpoint"/>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence>
<store messageStore="No1MessageStore"/>
<makefault version="soap11">
<code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:VersionMismatch"/>
<reason value="There has been an error"/>
<detail>We will retry later</detail>
</makefault>
<send/>
</faultSequence>
</target>
</proxy>
The message that is stored is the one made by the makefault in the TestProxy
I tried to save the original message in a property (in the inSequence) with
<property name="OriginalBody" expression="$body" scope="axis2" type="OM"/>
but in the faultSequence, when i do this :
<log level="custom">
<property name="OriginalBody" expression="get-property('OriginalBody')"/>
</log>
I got null as a result :(
Does anyone have an idea ?
Thanks !
remove scope "axis2" when defining property "OriginalBody" or explicitely specify scope="default" :
<property name="OriginalBody" expression="$body" type="OM"/>
I have custom mediator where we are validating internal authentication system. If authentication fails, mediator return false. Client receiving response as HTTP status code 202. This I want to override with some JSON response like { "authError" : "Authetication failed - TOKEN_INVALID" }. Please let me know how to handle such scenarios.
ESB Version - 4.81.
Here is my proxy configuration -
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="UGCGetJSONFileList"
transports="https,http"
statistics="enable"
trace="disable"
startOnLoad="true">
<target outSequence="WEB_OUT_Sequence">
<inSequence>
<log level="full" separator=","/>
<class name="com.hc.synapse.mediator.HCAuthenticationMediator"/>
<property name="RESPONSE" value="true" scope="axis2"/>
<property name="uri.var.querystrings"
expression="substring-after(get-property('To'), '?')"
scope="axis2"
type="STRING"/>
<log level="full" separator=","/>
<switch source="$axis2:HTTP_METHOD">
<case regex="GET">
<property name="uri.var.querystrings"
expression="substring-after(get-property('To'), '?')"
scope="default"
type="STRING"/>
<log level="full" separator=","/>
<send>
<endpoint>
<http method="get"
uri-template="http://dalx-entsvc-d1:9660/ugc/getJSONFileList?{uri.var.querystrings}"/>
</endpoint>
</send>
</case>
<case regex="POST">
<log level="full" separator=","/>
<send>
<endpoint>
<address uri="http://dalx-entsvc-d1:9660/ugc/getJSONFileList?{uri.var.querystrings};content"
trace="enable"
statistics="enable">
<timeout>
<duration>30000</duration>
<responseAction>discard</responseAction>
</timeout>
<suspendOnFailure>
<initialDuration>0</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</send>
</case>
<default/>
</switch>
</inSequence>
<faultSequence>
<log level="full" separator=",">
<property name="trace" expression="get-property('ERROR_MESSAGE')"/>
</log>
<payloadFactory media-type="json">
<format>{ "authError" : "Authetication failed - TOKEN_INVALID" }</format>
<args/>
</payloadFactory>
<property name="RESPONSE" value="true"/>
<header name="To" action="remove"/>
<send/>
</faultSequence>
</target>
<description/>
</proxy>
In your class mediator, you can throw a SynapseException
In this case, inSequence mediation stop and faultSequence will be executed
In the faultSequence, your can use mediator payloadFactory with media-type="json" to build your json message and send it to the client with <send/>
My Proxy Service deployed on ESB is calling another standalone REST service. This service returns HTTP status 200 along with some data in the response body. My question is how I can retrieve HTTP status from response. Here is my configuration:
<proxy name="CQProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<switch source="get-property('Action')">
<case regex="getTaskTicket">
<sequence key="GetTaskTicket"/>
</case>
<default/>
</switch>
</inSequence>
<outSequence>
<log>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="Status"
expression="get-property('HTTP_SC')"/>
</log>
<send/>
</outSequence>
<faultSequence/>
</target>
<publishWSDL key="gov:/services/cqproxy/CQProxy.wsdl">
<resource location="CQProxy.xsd" key="gov:/services/cqproxy/CQProxy.xsd"/>
</publishWSDL>
</proxy>
<sequence name="GetTaskTicket">
...
<property name="REST_URL_POSTFIX"
value="/16783484?oslc.select=dcterms:title,oslc_cm:status"
scope="axis2"
type="STRING"/>
<property name="HTTP_METHOD" value="GET" scope="axis2" type="STRING"/>
<send>
<endpoint>
<address uri="http://.../simpleQuery"
format="rest"/>
<property name="OSLC-Core-Version" value="2.0" scope="transport"/>
<property name="Accept" value="application/rdf+xml" scope="transport"/>
</endpoint>
</send>
</sequence>
...
I tried the following code:
<log>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Status" expression="get-property('HTTP_SC')"/>
</log>
And this one too:
<log>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Status" expression="get-property('axis2', 'HTTP_SC')"/>
</log>
But all of them returned null.
After reading WSO2 documentation in more details, I found the right answer:
<property xmlns:ns="http://org.apache.synapse/xsd" name="Status" expression="$axis2:HTTP_SC"/>
It is weird that the documented get-property('axis2', 'HTTP_SC') does not work.
Posting the solution that worked for me:
<property scope="default" type="STRING" name="HTTP_STATUS_CODE" expression="get-property('axis2', 'HTTP_SC')"/>
<log level="custom">
<property expression="get-property('HTTP_STATUS_CODE')" name="HTTP status code received: "/>
</log>