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
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.
In WSO2 ESB 490 I have wrote the simple API:
<api xmlns="http://ws.apache.org/ns/synapse" name="paramsTest" context="/params">
<resource methods="GET" uri-template="/p?try={params_list}">
<inSequence>
<property name="params_list" expression="get-property('uri.var.params_list')"/>
<log level="full">
<property name="The input params : " expression="get-property('params_list')"/>
</log>
<payloadFactory media-type="json">
<format>{"res_body":"$1"}</format>
<args>
<arg evaluator="xml" expression="get-property('params_list')"/>
</args>
</payloadFactory>
<respond/>
</inSequence>
</resource>
</api>
It work fine when access by URL:
http://localhost:8290/params/p?try=one
and response {"res_body":"one"}
But when access by this URL :
http://localhost:8290/params/p?try=one,two
It response nothing, and it seems ESB didn't process the request because of parameters "try=one,two" separate by comma.
How can make ESB process this URL?(parameters separate by comma)
AFAIK you need to encode the comma with %2C when using with url params.
e.g.
http://localhost:8290/params/p?try=one%2Ctwo
If you get the parameter list via a property you will get %2C encoded values with parameters. Have a look at the working example mentioned below.
<resource methods="POST" uri-template="?sessionId={id}">
<inSequence>
<property name="sessionId" expression="$url:sessionId"/>
Extract parameters one by one as mentioned above.
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.
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.
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.