Use variables for URI in WSDL mediators WSO2 - wso2

I am re-factorizing a wso2 project and I wondered how/whether I could do the following. This project is designed to send data to a SOAP Api. In every environment, this API exposes a .wsdl file and the URL and credentials are the only things changing from one environment to another. The most natural thing to do is thus to
create those in the Registry and
load it in the beginning of the job like so
<propertyGroup>
<property expression="get-property('registry', 'gov:/endpoints/sap_constructionSiteUser')" name="sap_constructionSiteUser" scope="default" type="STRING"/>
<property expression="get-property('registry', 'gov:/endpoints/sap_constructionSitePassword')" name="sap_constructionSitePassword" scope="default" type="STRING"/>
<property expression="get-property('registry', 'gov:/endpoints/sap_constructionSiteUrl')" name="uri.var.sap_constructionSiteUrl" scope="default" type="STRING"/>
</propertyGroup>
But I could not find a straightforward way to use this uri.var.sap_constructionSiteUrl in the endpoint definition. The following does not work
<call>
<endpoint>
<wsdl optimize="mtom" uri="{uri.var.sap_constructionSiteUrl}" port="OUVERTURE_CHANTIER" service="OUVERTURE_CHANTIER" statistics="enable">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</wsdl>
</endpoint>
</call>
Looks like uri= only accept plain value. Is there a way I could made this dynamic without writing the entire endpoint in the Registry (the point is to keep things simple for the clients)
[Environment]
wso2ei 6.5.0
====================EDIT========================
I just created a template:
<template name="crm4sap-constructionSiteTemplate" xmlns="http://ws.apache.org/ns/synapse">
<axis2ns488:parameter name="port" xmlns:axis2ns488="http://ws.apache.org/ns/synapse"/>
<axis2ns489:parameter name="service" xmlns:axis2ns489="http://ws.apache.org/ns/synapse"/>
<axis2ns490:parameter name="uri" xmlns:axis2ns490="http://ws.apache.org/ns/synapse"/>
<endpoint name="$name">
<wsdl port="$port" service="$service" uri="$uri">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1.0</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</wsdl>
</endpoint>
</template>
And I call it with
<call>
<endpoint name="constructionSiteEndpoint" template="crm4sap-constructionSiteTemplate">
<axis2ns468:parameter name="port" value="OUVERTURE_CHANTIER" xmlns:axis2ns468="http://ws.apache.org/ns/synapse"/>
<axis2ns469:parameter name="service" value="OUVERTURE_CHANTIER" xmlns:axis2ns469="http://ws.apache.org/ns/synapse"/>
<axis2ns469:parameter name="uri" value="{$ctx:sap_constructionSiteUrl}" xmlns:axis2ns469="http://ws.apache.org/ns/synapse"/>
</endpoint>
</call>
Variable substitution does not seem to occur:
[2020-04-15 12:30:54,032] [] WARN - TemplateEndpointFactory Could not read the WSDL endpoint {$ctx:sap_constructionSiteUrl}
java.net.MalformedURLException: no protocol: {$ctx:sap_constructionSiteUrl}
at java.net.URL.<init>(URL.java:600)
at java.net.URL.<init>(URL.java:497)
at java.net.URL.<init>(URL.java:446)
Looks like a common problem

You can try to template this endpoint and then call the template with the parameters. You can pass dynamic values to the template in the runtime.
https://docs.wso2.com/display/EI650/Endpoint+Template

I was able to do it using the following code in the sequence:
<call-template target="template-for-calling-soap">
<with-param name="url" value="{get-property('soap-uri')}"/>
</call-template>
Where soap-uri is a local entry or a simple property, and the sequence template named template-for-calling-soap takes as parameter the url value and has the following code:
<template name="template-for-calling-soap"
xmlns="http://ws.apache.org/ns/synapse">
<parameter name="url"/>
<sequence>
<property expression="$func:url" name="uri.var" scope="default"
type="STRING"/>
<send>
<endpoint>
<address format="soap11" uri="${uri.var}"/>
</endpoint>
</send>
</sequence>
</template>

Related

Unable to get the response from the API

Scenario
I'm sending a request payload to the API that further calls the SMS service provider in the in-sequence flow, I need to share back the response from the SMS service provider as it is. The API works fine and I do receive SMS on phone but I'm unable to share back the response from the service provider in the out sequence flow.
The response body from my SMS service provider is actually text as shown:
The Response header of SMS Service Provider looks like this:
API
<?xml version="1.0" encoding="UTF-8"?>
<api context="/mobilink" name="MobilinkSmsApi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/send">
<inSequence>
<property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/>
<property description="username" expression="json-eval($.username)" name="uri.var.username" scope="default" type="STRING"/>
<property description="password" expression="json-eval($.password)" name="uri.var.password" scope="default" type="STRING"/>
<property description="to" expression="json-eval($.to)" name="uri.var.to" scope="default" type="STRING"/>
<property description="from" expression="json-eval($.from)" name="uri.var.from" scope="default" type="STRING"/>
<property description="message" expression="json-eval($.message)" name="uri.var.message" scope="default" type="STRING"/>
<log level="full"/>
<call>
<endpoint>
<http method="post" statistics="enable" trace="enable" uri-template="https://coXXXXX.XXXX.com/sendsms_url.html?Username={uri.var.username}&Password={uri.var.password}&From={uri.var.from}&To={uri.var.to}&Message={uri.var.message}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</inSequence>
<outSequence>
<log category="TRACE" level="full"/>
<property description="Content-Type" name="Content-Type" scope="default" type="STRING" value="text/html"/>
<property name="messageType" scope="axis2" type="STRING" value="text/html"/>
<respond/>
</outSequence>
<faultSequence>
<log category="ERROR" level="full"/>
</faultSequence>
</resource>
</api>
Question
My Question is how to share back the response from the service provider in the out sequence? I tried to use property with value text/html and even used content-type as text/html but It didn't worked.
There are two ways to achieve this. either one of below mentioned way you can follow
place <respond/> after <call> mediator
Use <Send> mediator instead of <call>, so that flow will come from insequence to outsequence where you already placed <respond/> to send back message to client
The issue got resolved when I placed the mediator in the inSequence flow.
previously I was placing the mediator in the outSequence

Iterator mediator counter esb wso2

I'm using the iterate mediator for calculate the sum of a note variable i tried with the script mediator
but when i send the api in postman for test we takes a long time without answer and i have this error :
ERROR {PassThroughNHttpGetProcessor} - Unable to find axis service for service name : studenttest/getsomme
here is my code:
<resource methods="GET" uri-template="/gettotal">
<inSequence>
<property expression="$url:nom" name="uri.var.nom" scope="default" type="STRING"/>
<call>
<endpoint>
<http method="get" uri-template="http://ITMTNF3RRJSJ:8290/services/studenttest/getsomme?nom={uri.var.nom}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<property name="it_count" scope="operation" type="STRING" value="0"/>
<iterate expression="//symbols/symbol" sequential="TRUE">
<target>
<sequence>
<property expression="json-eval($.note)" name="note" scope="default" type="STRING"/>
<script language="js"><![CDATA[var note = mc.getProperty('note');
var totalnote =it_count+note;
mc.setProperty('it_count', totalnote);]]></script>
</sequence>
</target>
</iterate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
This error "Unable to find axis service for service name" is a known issue[1] when a data service is invoked as a Rest service with query parameters in MI-1.2.0 and this is already fixed in MI-1.2.0 with the latest updates. If you have a valid wso2 subscription you can get the latest updates using the Update 2.0 tool[2].
However, you can invoke the data service in soap manner or rest manner without query parameters and check the mediation.
[1] https://github.com/wso2/micro-integrator/issues/2351
[2] https://updates.docs.wso2.com/en/latest/

Message Details are not shown in Apache ActiveMQ 5.16.3 with WSO2 EI 6.5.0

I'm using WSO2 EI 6.5.0 to send message to activemq 5.16.3. I have followed this blog steps to set up WSO2 EI and ActiveMQ.
API Code:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/activemqsapi" name="ActiveMQAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<log level="custom">
<property name="===ActiveMQAPI" value="is called===="/>
</log>
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<send>
<endpoint>
<address uri="jms:/WSO2EIQ?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</address>
</endpoint>
</send>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Message Details are shown like below in activeMQ.
Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: org.apache.synapse.message.store.impl.commons.StorableMessage
As per this question i have added property in %ACTIVEMQ_HOME%\bin\win64\wrapper.conf which also not working.
wrapper.java.additional.13=Dorg.apache.activemq.SERIALIZABLE_PACKAGES="*"
Can anyone help me on this?
As per this doc, added below line in windows.bat file which resolved my issue.
org.apache.activemq.SERIALIZABLE_PACKAGES="*"
Now I can able to see newly posted message in active-mq console.

executing default fault sequence error code 303001 wso2 esb

i have a proxy service that call a web service . sometimes it send out error code 303001 and after refresh it work again . my mind of refresh is i open admin panel in list of service choose design view of my service and click next next finish. after that service work correctly and after 1 hour it throw out error code
my service :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="BillVerification"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<class name="org.sample.mediators.citydi.HashMediatorCityDI"/>
<log level="full" category="FATAL">
<property name="fprever" value="justyou"/>
</log>
<property name="DISABLE_CHUNKING"
value="true"
scope="axis2"
type="STRING"/>
<send>
<endpoint>
<address uri="http://checkbill2.citydi.net/CheckBill.asmx?wsdl" format="soap12">
<suspendOnFailure>
<initialDuration>100000000</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>100000000</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</send>
<log level="full" category="FATAL">
<property name="send1" value="send1"/>
</log>
</inSequence>
<outSequence>
<log level="full">
<property name="beforeSENDout" value="2"/>
</log>
<send/>
<log level="full" category="FATAL">
<property name="send2" value="send2"/>
</log>
</outSequence>
</target>
<publishWSDL uri="http://checkbill2.citydi.net/CheckBill.asmx?wsdl"/>
<description/>
</proxy>
303001 = Address Endpoint is not ready to connect
Perhaps because of a corporate proxy / firewall ?
You'r wrong thinking your endpoint is active always : use a named endpoint instead of your anonymous one and have a look to wso2 web console : I guess it will be deactivated (the "action" become "Switch on")
In your case, with an anonymous endpoint, when you edit / save your proxy, the endpoint is switched on.
If you don't want your endpoint to be suspended add something like this :
<suspendOnFailure>
<errorCodes>-1</errorCodes>
<initialDuration>0</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
If you don't want your endpoint to manage a specific timeout, add something like this :
<markForSuspension>
<errorCodes>-1</errorCodes>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
<retryDelay>0</retryDelay>
</markForSuspension>

Wso2 Esb sequence template calling endpoint template

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