i was trying out file upload program , i get exception in script mediator while setting binay = true . following is code
<?xml version="1.0" encoding="UTF-8"?>
<api context="/v1/document" name="DocUpload" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" url-mapping="/upload">
<inSequence>
<log level="full"/>
<property expression="json-eval($.fileName)" name="fileName" scope="default" type="STRING"/>
<property expression="json-eval($.fileContent)" name="fileContent" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:binary>
</format>
<args>
<arg evaluator="xml" expression="$body/attachments/content"/>
</args>
</payloadFactory>
<script language="js"><![CDATA[var binaryNode =
mc.getEnvelope().getBody().getFirstElement().getFirstOMChild();
binaryNode.setBinary(true);]]></script>
<log level="full">
<property expression="$ctx:fileName" name="fileName"/>
</log>
Exception as follows
"fileContent": "Base64 IMAGECONTENT"}/request/mediate/soapenv:Body/soapenv:Envelope
[2020-07-03 17:48:21,346] ERROR {org.apache.synapse.mediators.bsf.ScriptMediator} - The script engine returned an error executing the inlined js script function mediate com.sun.phobos.script.util.ExtendedScriptException: org.mozilla.javascript.EcmaError: TypeError: Cannot call method "setBinary" of null (Unknown Source#3) in Unknown Source at line number 3
I have upload the file using POSTMAN , by calling API as shown below
, Any help appreciated
It seems that you are sending the message body as a header in the postman (request {
"fileName":"imageNew2.png",
"fileContent": "Base64 IMAGECONTENT"
})
Instead of this please try to send the request payload as the body (use a POST request).
If you are interested in working with files please refer to the VFS transport and also the file connector operation in 1, [2].
[1] -https://docs.wso2.com/display/ESB500/VFS+Transport
[2]-https://docs.wso2.com/display/ESBCONNECTORS/File+Connector
Related
I have the following API in EI 6.6.0:
<?xml version='1.0' encoding='UTF-8'?>
<api xmlns="http://ws.apache.org/ns/synapse" name="sample" context="/sample">
<resource methods="POST">
<inSequence>
<payloadFactory media-type="xml">
<format>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<P xmlns="http://tempuri.org/">
<P1>$1</P1>
<P2>$2</P2>
<P3>$3</P3>
</P>
</soap:Body>
</soap:Envelope>
</format>
<args>
<arg evaluator="json" expression="$.p1" />
<arg evaluator="json" expression="$.p2" />
<arg evaluator="json" expression="$.p3" />
</args>
</payloadFactory>
<log level="full" />
<property name="Content-Type" value="text/xml;charset=UTF-8" scope="axis2"/>
<header name="Accept" scope="transport" value="text/xml"/>
<call>
<endpoint>
<wsdl Action="name_of_the_action" service="name_of_the_service" port="name_of_soap_port" uri="http://<ip>/path?WSDL" />
</endpoint>
</call>
<class name="my_mediator_package"></class>
<log level="full" />
<payloadFactory media-type="xml">
<format>
<retorno xmlns="">
<msg>$1</msg>
</retorno>
</format>
<args>
<arg evaluator="xml" expression="get-property('property_set_on_mediator')" />
</args>
</payloadFactory>
<property name="messageType" value="application/xml" scope="axis2" type="STRING" />
<respond />
</inSequence>
<outSequence>
</outSequence>
<faultSequence>
<property name="text" value="An unexpected error occured"/>
<property name="message" expression="get-property('ERROR_MESSAGE')"/>
<payloadFactory media-type="xml">
<format>
<error xmlns="">
<msg>$1</msg>
</error>
</format>
<args>
<arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<respond/>
</faultSequence>
</resource>
</api>
my mediate method content:
public boolean mediate(MessageContext synCtx) {
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) synCtx)
.getAxis2MessageContext();
try {
// Getting the json payload to string
String jsonPayloadToString = JsonUtil.jsonPayloadToString(((Axis2MessageContext) synCtx)
.getAxis2MessageContext());
System.out.println("original payload : \n" + jsonPayloadToString + "\n");
I'm not being able to use the return from my SOAP call in my mediator so I can work on it.
When I run the API I get the following from my mediator code:
original payload:
{}
Is there a way so I can obtain the SOAP call returned envelope and use it in my mediator?
The JSON payload is coming as empty because you are calling a SOAP backend and getting a SOAP payload. You can use synCtx.getEnvelope() in your mediator to get the SOAPEnvelope from the response.
1- make sure the json payload is there. So, log the json properties inside your inSequence.
2- I'm not being able to use the return from my SOAP call in my mediator so I can work on it. you can see the response payload in your outSequence which currently is doing nothing.
3- According to your scenario which is simply calling a SOAP webservice, you do not need a class mediator. In other words, when you do not need manipulating the initial payload and then pass it to the destination service, logically implementing your own class mediator benefits you nothing.
Also, there are quite number of samples in https://docs.wso2.com/display/EI611 which will help you.
Please let me know if your problem is solved.
In our project we are using WSO2 API Manager v 2.1.0. Our goal is to write a fault sequence that will log some information in custom logfile, example timestamp, name of the API etc. I was able to create a file and write to it, but it does not work as expected. Things I need to have is
Control the file name
Append content to file instead of overwriting it each time
This is the sequence I am using (simplified easier reading):
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="admin--FaultyAPI2:v1.0.0--Fault">
<clone continueParent="true">
<target>
<sequence>
<property xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:ns3="http://org.apache.synapse/xsd" name="destination" expression="get-property('To')"/>
<format>
{
"destination_host" : "$1"
}
</format>
<args>
<arg xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:ns3="http://org.apache.synapse/xsd" evaluator="xml" expression="get-property('destination')"/>
</args>
</payloadFactory>
<property name="transport.vfs.ReplyFileName" value="test.txt" scope="transport" type="STRING"/>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<send>
<endpoint>
<http uri-template="vfs:file:///home/install/out?transport.vfs.Append=true"/>
</endpoint>
</send>
</sequence>
</target>
</clone>
</sequence>
Following documentation I have used transport.vfs.ReplyFileName to specify the file name and ?transport.vfs.Append=true path parameter to tell it to append to file. The problem is that those two things are ignored.
First thing is that the file created is not test.txt but it is the endpoint URI that failed (the one I have setup in API Manager). So if I call /fault endpoint the file created is fault under location specified.
The second thing is that it is not appending to a file, but overwriting it each time the sequence is triggered. It is even worse! It creates actual path /home/install/out?transport.vfs.Append=true on file system and saves the file under this directory.
Those features seems to work under WSO ESB, but not API Manager. Any ideas anyone?
First of all, I have tested this in WSO2 EI, not in API Manager, but it seemed to me, the same problems you described appeared.
Controlling the filename
I've had some issues with this as well. The problem is that when you call the sequence through an API, the filename is not constructed based on the "transport.vfs.ReplyFileName" transport property, but based on the "REST_URL_POSTFIX" axis2 property. You can solve this by setting the "REST_URL_POSTFIX" property to the correct filename or by removing that property.
Appending the content
You are using an http endpoint, but you should use an address endpoint. In that case the path parameter will be recognized.
Example
I think your code should look more like this:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="admin--FaultyAPI2:v1.0.0--Fault" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<clone continueParent="true">
<target>
<sequence>
<payloadFactory media-type="json">
<format>
{
"destination_host" : "$1"
}
</format>
<args>
<arg evaluator="xml" expression="get-property('destination')" xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"/>
</args>
</payloadFactory>
<property name="transport.vfs.ReplyFileName" scope="transport" type="STRING" value="test.txt"/>
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
<property name="REST_URL_POSTFIX" action="remove" scope="axis2" />
<send>
<endpoint>
<address uri="vfs:file:///home/install/out?transport.vfs.Append=true"/>
</endpoint>
</send>
</sequence>
</target>
</clone>
</sequence>
Scenario:
I have a vfs-Proxy monitoring a folder for files with the extention .pdf.
The Proxy parses the file-content in base64binary into
<axis2ns#:binary xmlns:axis2ns#="http://ws.apache.org/commons/ns/payload">JVBERi0xLjMKJfbk/N8K...</axis2ns#:binary>
# is a incremental number and as far as i know, i don't have an influence on this mater. With a payloadFactory i reformat the payload to be surrounded by
<datatype:pdf xmlns:datatype="http://mynamespace.org/payload"> instead.
Problem:
The resulting file looks like this:
--MIMEBoundary_e1f5b2321e28e0a638b52a178d5c7ee40c2f3ae08cd43818
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <0.f1f5b2321e28e0a638b52a178d5c7ee40c2f3ae08cd43818#apache.org>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<datatype:pdf xmlns:datatype="http://mynamespace.org/payload">
JVBERi0xLjMKJfbk/N8K...
</datatype:pdf>
</soapenv:Body>
</soapenv:Envelope>
--MIMEBoundary_e1f5b2321e28e0a638b52a178d5c7ee40c2f3ae08cd43818--
instead of an actual pdf-document. What's necessary to change that? I'm pretty sure it has so be something with the content-types or the payloadFactory. Is there a way to specify which tags are treated as payload? I have already tried to a few different types, settings and searched but coudn't find a solution. If i interpret the resulting message correct mtom isn't working as it is supposed to. Shouldn't there be a
<xop:Include href="...">
inside the resulting message instead of the inline base64binary?
Simple Code for reproduction:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="VFSVFS"
transports="vfs"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<property name="enableMTOM" value="true" scope="axis2" type="STRING"/>
<property name="enableSWA" value="false" scope="axis2" type="STRING"/>
<property name="transportNonBlocking"
value="true"
scope="axis2"
action="remove"/>
<payloadFactory media-type="xml">
<format>
<datatype:pdf xmlns:datatype="http://mynamespace.org/payload">
$1
</datatype:pdf>
</format>
<args>
<arg evaluator="xml" expression="$body/*[1]"/>
</args>
</payloadFactory>
<property name="messageType" value="application/octet-stream" scope="axis2"/>
<property name="transport.vfs.ReplyFileName" expression="fn:concat(fn:substring-after(get-property('MessageID'), 'urn:uuid:'), 'abc.pdf')" scope="transport"/>
<property name="transport.vfs.Streaming" value="true" scope="transport" type="STRING"/>
<send>
<endpoint xmlns="http://ws.apache.org/ns/synapse" name="FileOut_VFS">
<address uri="vfs:file:///home/user/Development/data/testfiles/init/out" optimize="mtom" />
</endpoint>
</send>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
</inSequence>
</target>
<parameter name="transport.vfs.ActionAfterProcess">DELETE</parameter>
<parameter name="transport.PollInterval">5</parameter>
<parameter name="transport.vfs.FileURI">file:///home/user/Development/data/testfiles/init/in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file:///home/user/Development/data/failure</parameter>
<parameter name="transport.vfs.Locking">false</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.pdf</parameter>
<parameter name="transport.vfs.ContentType">application/octet-stream</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<parameter name="transport.vfs.FailedRecordsFileDestination">file:///home/user/Development/data/failure</parameter>
<description/>
</proxy>
The code above is just for the purpose of simplification. The actual project performs those key operations:
read-in a pdf
aggregate the soap-message with additional information from various sources
manipulate the pdf-content with a custom mediator
write-out the new pdf
For the purpose of aggregation and manipulation i want to reformat the initial body with the payloadFactory. But as soon as I change a thing, the message no longer arrives in a fitting format.
This applies even in the simple code above.
Here a few examples of tried out combination's and their results:
<ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:binary>
WITH OR WITHOUT
<property name="ContentType" value="application/octet-stream" scope="axis2"/>
RESULTS IN
INFO - AxisEngine [MessageContext: logID=6143bc348d4852f3ffa02dba72391ab0860fe7c27625f167] ContentID is null
[2015-10-16 08:19:40,923] ERROR - AsyncCallback ContentID is null
java.lang.RuntimeException: ContentID is null
EVEN WITH <property name="enableMTOM" value="false" scope="axis2" type="STRING"/>
<ns:text xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:text>
WITH OR WITHOUT
<property name="ContentType" value="application/octet-stream" scope="axis2"/> RESULTS IN
File with base64binary as plain/text in it -> no functioning pdf.
I guess, you should change the format to the following so it will be treated as text.
<format>
<ns:text xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:text>
</format>
Hope that helps. I guess you won't be able to open the file because it will have the wrong encoding.
Regards
Martin
Not sure if I get it right. If I look at the proxy it seems that you'd like to read a pdf and write it to some other location. So you just could use the following to write the file.
<send>
<endpoint>
<address uri="vfs:file:///home/user/Development/data/testfiles/init/out"/>
</endpoint>
</send>
Inside the ESB every message/file that arrives will be converted to a soap message.
Regards
Martin
From this post on the ws-commons-dev mailing list finally send me in the right direction.
The problem is that to make this work the OMElement object has be have a Content ID OR have the flag isBinary set to true.
This is a attribute on the OMTextImpl and from what I can tell this has to be done on the object and can not be set from the XML payload. So in the end I had to add a script mediator to do this.
<payloadFactory media-type="xml">
<format>
<ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:binary>
</format>
<args>
<arg evaluator="xml" expression="$body/attachments/content"/>
</args>
</payloadFactory>
<script language="js">
<![CDATA[
var binaryNode =
mc.getEnvelope().getBody().getFirstElement().getFirstOMChild();
binaryNode.setBinary(true);
]]>
</script>
In the example above the base64 data comes in as part of the incoming message.
Implementing a service chain in WSO2 ESB 4.8.1 we have a sequence that calls a REST service and in the receiving sequence we call a SOAP service. In doing so, we get the following error,
<?xml version='1.0' encoding='utf-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body><ns2:Fault xmlns:ns3="http://www.w3.org/2003/05/soap-envelope" xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/"><faultcode>ns2:Client</faultcode>
<faultstring>Couldn't create SOAP message due to exception: XML reader error: com.ctc.wstx.exc.WstxIOException: Invalid UTF-8 start byte 0x8b (at char #2, byte #-1)</faultstring>
</ns2:Fault>
</S:Body>
</S:Envelope>[\r][\n]" {org.apache.synapse.transport.http.wire}
This happens irrespective of whether we use the result of the previous call as input or even when actual values are hard-coded in the PayloadFactory. Moreover the SOAP service never receives the request.
When the SOAP service is called on it's own through the ESB or through soapUI, it works fine.
The sequence that calls the SOAP service is as follows,
<template xmlns="http://ws.apache.org/ns/synapse" name="tmpl_get_customer_details">
<sequence>
<payloadFactory media-type="xml">
<format>
<getCustomer xmlns="http://customer.frontend.ws.utilibill.com.au/">
<customer xmlns="">
<custNo>12965</custNo>
</customer>
<login xmlns="">
<password>password</password>
<userName>username</userName>
</login>
</getCustomer>
</format>
<args>
<arg xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" expression="$ctx:utilibill_customer_number" evaluator="xml"></arg>
</args>
</payloadFactory>
<log level="full">
<property name="POSITION" value="tmpl_get_customer_details"></property>
</log>
<header name="Action" scope="default" value="http://customer.frontend.ws.utilibill.com.au/UtbCustomer/getCustomerRequest"></header>
<header name="To" scope="transport" value="http://customer.frontend.ws.utilibill.com.au/UtbCustomer/getCustomerRequest"></header>
<property name="POST_TO_URI" value="true" scope="axis2" type="STRING"></property>
<log level="full">
<property name="POSITION" value="CALLING_CUSTOMER_SERVICE"></property>
</log>
<send receive="seq_get_services">
<endpoint key="UtbCustomer"></endpoint>
</send>
</sequence>
</template>
Can anyone please point out what maybe causing this?
My current scenario is that i have a web service exposed from data service which returns me email address of the user when i give it the name of the user. Now i want to use this web service in ESB and get the email id from this web service in a property and show it in console using LOG mediator.
What should i do now and how?
Sorry for this silly question but i am newest member of wso2 esb. So please help me on this.
Now ihave a response like:
<brs:getRecipientKeyResponse xmlns:brs="http://brs.carbon.wso2.org">
<brs:MailRecipient xsi:type="ax2338:MailRecipient" xmlns:ax2338="http://email.samples/xsd" xmlns:ax2337="http://email.samples/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ax2337:recipient>kevin</ax2337:recipient>
</brs:MailRecipient>
</brs:getRecipientKeyResponse>
Ihave to get the recipient element from this response and put this in payload. My complete sequence for this is:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="receiveSeq">
<log>
<property name="getRecipient" value="------------Trying to get data Fom BRS Response----------------------------"/>
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ax2337="http://email.samples/xsd" name="Recipient" expression="//ax2337:recipient"/>
</log>
<payloadFactory>
<format>
<p:GetEmailDetails xmlns:p="http://ws.wso2.org/dataservice">
<xs:name xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:name>
</p:GetEmailDetails>
</format>
<args>
<arg xmlns:ns="http://org.apache.synapse/xsd" xmlns:ax2337="http://email.samples/xsd" expression="//ax2337:recipient"/>
</args>
</payloadFactory>
<log>
<property xmlns:ns="http://org.apache.synapse/xsd" name="getName" expression="get-property('Recipient')"/>
</log>
<send receive="DBSeq">
<endpoint key="emailServiceEP"/>
</send>
</sequence>
<!--this part is not able to get data --->
<property xmlns:ns="http://org.apache.synapse/xsd" name="getName" expression="get-property('Recipient')"/>
u just use the the your wso2dss tryit service in that request side code copy into the payloadfactory insted of " ? " keep the $1 ,$2 ..like this and pass the argument below as per ur above order order is play a vital role for this response i think it will help for u
<payloadFactory>
<format>
<p:insert_emp_operation xmlns:p="http://ws.wso2.org/dataservice">
<xs:eno xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:eno>
<xs:ename xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:ename>
<xs:esal xmlns:xs="http://ws.wso2.org/dataservice">$3</xs:esal>
</p:insert_emp_operation>
</format>
<args>
<arg expression="get-property('eno')"/>
<arg expression="get-property('ename')"/>
<arg expression="get-property('esal')"/>
</args>
</payloadFactory>
<send receive="Error_Seq">
<endpoint>
<address uri="http://localhost:9764/services/emp_DataService/" format="soap11"/>
</endpoint>
</send>
Since you have the Dataservice is implemented, give that as endpoint url to your proxy which can be created in wso2esb. When you send request to your proxy,in the outsequence, you will receive the response of your dataservice. Just do a log with "level=full" you will see the full response. Use the property mediator and do an xpath to pick the value which you needed.
Sample conf:
<proxy name="StockQuoteProxy">
<target>
<endpoint>
<address uri="DS endpoint"/>
</endpoint>
<outSequence>
<log level="full">
<property name="email" expression="xpath from the email attribute in the rseponse"/>
</log>
<send/>
</outSequence>
</target>
</proxy>
Here is esb sample guide on how to create proxies;
http://docs.wso2.org/wiki/display/ESB460/Proxy+Service+Samples