wso2 esb Class Mediator - wso2

hello I have the following class mediator created through Carbon Studio:
package my.mediation;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
public class Auth extends AbstractMediator {
public boolean mediate(MessageContext context) {
// TODO Implement your mediation logic here
context.setProperty("message","hello world!" );
return true;
}
}
And the sequence is like:
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<property name="message" value="nothing" scope="default" />
<class name="my.mediation.Auth" />
<log>
<property name="Message******" expression="get-property('message')" />
</log>
</inSequence
>
The problem is that instead of printing Message: "HelloWorld" it always print the text "nothing"...Any suggestion?

Your scenario is perfectly valid one and your configuration also seems to be fine.
I have tied your scenario and it works fine for me.
Following are my configurations.
Class Mediator:
package org.wso2.mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
public class SampleMediator extends AbstractMediator {
public boolean mediate(MessageContext context) {
context.setProperty("Message", "HelloWorld!");
return true;
}
}
My proxy service:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="SimpleProxy"
statistics="disable" trace="disable" transports="http,https">
<target>
<inSequence>
<log category="INFO" level="simple" separator=","/>
<property action="set" name="Message" scope="default"
type="STRING" value="DefaultMessage"/>
<class name="org.wso2.mediator.SampleMediator"/>
<log category="INFO" level="simple" separator=",">
<property expression="get-property('Message')" name="===========Message Value=========="/>
</log>
<drop/>
</inSequence>
</target>
</proxy>
When I invoke the proxy service without the class mediator, it prints
INFO - LogMediator To: /services/SimpleProxy.SimpleProxyHttpSoap12Endpoint,WSAction: urn:mediate,SOAPAction: urn:mediate,MessageID: urn:uuid:81150094-cbc4-44f7-83eb-251e28149564,Direction: request,===========Message Value========== = DefaultMessage
and when I invoke the proxy service with the class mediator it prints,
INFO - LogMediator To: /services/SimpleProxy.SimpleProxyHttpSoap12Endpoint,WSAction: urn:mediate,SOAPAction: urn:mediate,MessageID: urn:uuid:e3a04341-907c-40fe-9f58-5a10d2ce346a,Direction: request,===========Message Value========== = HelloWorld!
Hope this helps!
Harshana

The problem is based in the log4j.properties. Your class is in the package my.mediation; which does not exist in the log4j.properties. You need to go to the YOUR_WSO2/lib/log4j.properties and add the level of the log for your namespace/package:
...
log4j.logger.org.wso2=INFO
log4j.logger.my.mediation=DEBUG
Here you see also why the example from Harashana worked - he just changed the package to org.wso2 - which you should not do for your own custom mediators.

Related

WSO2 ESB FileConnector MergeFiles does not produce expected results

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.

How to call python script file from wso2 proxy services

How to call python script file from wso2 proxy service.
We tried with send mediator to call the python script file which is located in my local machine.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="FilepythonTest"
transports="http https"
startOnLoad="true">
<description/>
<target >
<inSequence>
<send>
<endpoint>
<address uri="local:///Users/vikashsaharan/Desktop/python/testpy.py"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full"/>
</outSequence>
</target>
</proxy>
We are unable to call with this call. Please guide me how can i call python script from wso2
WSO2 EI has the inbuilt capability to execute a python script using the Script mediator. Following is a sample configuration.
**sample api configuration**
<api xmlns="http://ws.apache.org/ns/synapse" name="api" context="/api-context">
<resource methods="POST GET">
<inSequence>
<log level="full">
<property name="Message" value="Before transformation"/>
</log>
<script language="py" key="conf:/repository/script/stockquoteTransformResponse.py" function="transformRequest"/>
<log level="full">
<property name="Message" value="After transformation"/>
</log>
<respond/>
</inSequence>
</resource>
</api>
**stockquoteTransformResponse.py file saved in carbon registry.**
from org.apache.synapse.util.xpath import SynapseXPath
def transformRequest(mc):
symbolXPath = SynapseXPath("//*[local-name()='Code']/text()")
symbol = symbolXPath.stringValueOf(mc)
mc.setPayloadXML('''
<m:getQuote xmlns:m="http://services.samples">
<m:request>
<m:symbol>''' + symbol + '''</m:symbol>
</m:request>
</m:getQuote>''')
We need to add the jython jar to WSO2EI_HOME/lib directory. This was tested with jython-2.2.1.jar from http://central.maven.org/maven2/org/python/jython/2.2.1/jython-2.2.1.jar
Following output can be seen once we invoke the above api.
You can use a class mediator and execute a python script from there. Following is a sample class mediator that would do this.
public boolean mediate(MessageContext context) {
String command = "python /path/to/script.py";
try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String ret = in.readLine();
System.out.println("value is : "+ret);
} catch (IOException e) {
// handle exception
}
return true;
}
You can refer Running a .py file from Java

WSO2ESB concat input file name with SYSTEM_DATE

I am going to concat input file name with SYSTEM_DATE below is the code
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="importclassroomcourse"
transports="https,http,local"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log level="custom">
<property name="transport.vfs.ReplyFileName"
expression="fn:concat(get-property('SYSTEM_DATE', 'yyMMddHHmmss'), '-', get-property('filename'), '.xml')"/>
</log>
</inSequence>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="https://qa-abc.com/api/classroom/xyz"/>
</endpoint>
</target>
<description/>
</proxy>
But it won't concat the file name below is the log
LogMediator transport.vfs.ReplyFileName = 160316122250-.xml
Kindly guide me how can i get the file name because file name is missing.I have sent the file test.xlsx
I can't find any initialisation of property 'filename' in your mediation : this property does not exist and therefore, has no value when used in 'concat'.
What do you mean by "I have sent the file text.xlsx" ? Your proxy use http and local transport, it's not a VFS proxy scanning a directory to load files ?
You can define this property :
<property name="transport.vfs.ReplyFileName" expression="fn:concat(get-property('SYSTEM_DATE', 'yyMMddHHmmss'), '-test.xml')"/>
but after that, you must use send with a vfs endpoint inside the inSequence to write the file (in your case, there is a https endpoint)
If your proxy were a VFS proxy, you could use FILE_NAME on scope transport to get incoming filename.

Mapping optional query params in WSO2 ESB API resource

I have to mapping query params to send request to endpoint in API resource in WSO2 ESB.
Those query params are optional. For example, the following are examples of calls to resource:
http://server:port/service?q1={q1}
http://server:port/service?q2={q2}&q3={q3}
I need to have a single resource to do this.
How can I do this?
Basically, I have to read query params in request and put it in the call to endpoint uri.
You can have dynamic URIs using url-mapping attribute.
Here is an example:
<api xmlns="http://ws.apache.org/ns/synapse" name="test_api" context="/testService">
<resource methods="GET" url-mapping="/*">
<inSequence>
<log level="full">
<property name="paramQ1" expression="$ctx:query.param.q1"></property>
<property name="paramQ2" expression="$ctx:query.param.q2"></property>
<property name="paramQ3" expression="$ctx:query.param.q3"></property>
</log>
<send>
<endpoint>
<address uri="http://localhost:9766/services/"></address>
</endpoint>
</send>
</inSequence>
<outSequence>
<send></send>
</outSequence>
</resource>
</api>
To validate the presence of those query params its possible to use Filter Mediator. A good example of it can be found here.
Hope it helps.

Log into proxy log file each proxy duration

We need to log into the logs file of WSO2ESB , the duration of each call of proxy instances.
For example :
....
10:10:14,736 [MessageID : xxxxxxxxx] [duration : 259 ms]
....
It means that the proxy call associated to MessageID xxxxxxxx had a duration of 259 ms.
I don't want to active statistics mediator or BAM mediator.
Any idea to dot it easily ?
Tks
Nicolas
You can use SYSTEM_TIME property which is a Synapse Message Context Property. Using this you can get the current time in milliseconds in the desired places of the message flow and set the values as a properties. Then you can use the Script Mediator to write a small script (Javascript or Ruby) which reads the time values (stored in propeties) and do the neccessary calculations. You can display the result either in the script mediator or you can set it to a new propety so that it can be loged inside the proxy.
Synapse Message Context Propeties
http://docs.wso2.org/display/ESB470/Synapse+Message+Context+Properties
Using Script Mediator
http://docs.wso2.org/pages/viewpage.action?pageId=26838871
Log Mediator
http://docs.wso2.org/display/ESB470/Log+Mediator
Following sample might help you.
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="SampleTimeProxy"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="TIME_1"
expression="get-property('SYSTEM_TIME')"
scope="default"
type="LONG"/>
</inSequence>
<outSequence>
<send/>
<property name="TIME_2"
expression="get-property('SYSTEM_TIME')"
scope="default"
type="LONG"/>
<script language="js">var time1 = mc.getProperty("TIME_1");
var time2 = mc.getProperty("TIME_2");
var timeTaken = time2 - time1;
print("-------------- " + timeTaken + " ms -----------------");
mc.setProperty("RESPONSE_TIME", timeTaken);
</script>
<log>
<property name="time" expression="get-property('RESPONSE_TIME')"/>
</log>
</outSequence>
<endpoint>
<address uri="http://localhost:8080/axis2/services/SimpleStockQuoteService"/>
</endpoint>
</target>
<publishWSDL uri="http://localhost:8080/axis2/services/SimpleStockQuoteService?wsdl"/>
<description/>
</proxy>