Recently was working on a project where I had a to read an XML file from an FTP location, transform it and expose it as an API. Used WSO2 ESB 4.6.0 for this usecase; and I thought of documenting it for later reference. So here it goes
First the proxy that read the file from FTP and dump it to a defined location, (VFSProxy.xml)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<proxy xmlns="http://ws.apache.org/ns/synapse" name="VFSProxy" transports="vfs" startOnLoad="true" trace="disable"> | |
<target> | |
<inSequence> | |
<log level="custom"> | |
<property name="STATUS" value="File received"/> | |
</log> | |
<property name="OUT_ONLY" value="true"/> | |
<send> | |
<endpoint> | |
<address uri="vfs:file:///home/nuwanbando/temp/files/out"/> | |
</endpoint> | |
</send> | |
</inSequence> | |
</target> | |
<parameter name="transport.PollInterval">10</parameter> | |
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter> | |
<parameter name="transport.vfs.FileURI">vfs:ftp://<ftpserver_url>/home/nuwanbando/temp/files/in?vfs.passive=true</parameter> | |
<parameter name="transport.vfs.MoveAfterProcess">file:///home/nuwanbando/temp/files/processed</parameter> | |
<parameter name="transport.vfs.MoveAfterFailure">file:///home/nuwanbando/temp/files/failed</parameter> | |
<parameter name="transport.vfs.FileNamePattern">.*.xml</parameter> | |
<parameter name="transport.vfs.ContentType">text/plain</parameter> | |
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter> | |
</proxy> |
This proxy will dump the file to "home/nuwanbando/temp/files/out"
location.
This file need to be read on-demand, once requested. ESB by default does not have a mediator to read XML files so that the mediation flow can manipulate the content, hence we have to write a custom class mediator to do this job. The code is as follows,
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.sample; | |
import org.apache.axiom.om.OMElement; | |
import org.apache.axiom.om.impl.builder.StAXOMBuilder; | |
import org.apache.synapse.MessageContext; | |
import org.apache.synapse.mediators.AbstractMediator; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.InputStream; | |
public class XMLProcessMediator extends AbstractMediator { | |
public static final String FILE_LOCATION = "FileLocation"; | |
public static final String FILE_OM_ELEMENT = "FileOMElement"; | |
public boolean mediate(MessageContext context) { | |
String filePath = (String) context.getProperty(FILE_LOCATION); | |
File xmlFileToProcess = new File(filePath); | |
if (xmlFileToProcess.exists()) { | |
OMElement fileElement; | |
try { | |
InputStream xmlInputStream = new FileInputStream(xmlFileToProcess); | |
fileElement = new StAXOMBuilder(xmlInputStream).getDocumentElement(); | |
} catch (Exception e) { | |
log.error("Error while parsing XML file : " + xmlFileToProcess.getAbsolutePath()); | |
return false; | |
} | |
if (fileElement != null) { | |
context.setProperty(FILE_OM_ELEMENT, fileElement); | |
context.getEnvelope().getBody().addChild(fileElement); | |
} | |
} else { | |
return false; | |
} | |
return true; | |
} | |
} |
The code will read the file and add it to the synapse message context as an OMElement.
Now we will write a sequence which uses this class mediator; read the file and transform it through an XSLT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<sequence name="xmlProcessSeq"> | |
<header name="To" action="remove"/> | |
<property name="RESPONSE" value="true"/> | |
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/> | |
<property name="FileLocation" | |
value="home/nuwanbando/temp/files/out/catalog.xml" | |
scope="default" | |
type="STRING"/> | |
<class name="org.sample.XMLProcessMediator"/> | |
<xslt key="conf:/xslt/trans.xslt"/> | |
<send/> | |
</sequence> |
Next attach this sequence to an API, and expose it as a REST endpoint
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<api name="sampleAPI" context="/music"> | |
<resource methods="GET" | |
uri-template="/catalogs/*" | |
inSequence="xmlProcessSeq"/> | |
</api> |
That’s pretty much it.
important: This sample is tested on ESB 4.6.0 only;
Thanks, very nice. However it will be more ‘complete’ for novices like me to have either additional steps on starting points and deployment or point to those links.
LikeLike
Hi Auroir
ESB samples can be found at [1] and deployment/startup is at [2]
[1] http://docs.wso2.org/wiki/display/ESB470/Samples
[2] http://docs.wso2.org/wiki/display/ESB470/Running+the+Product
LikeLike
Thanks for the links, I am already familiar with those. My bad if I wasn’t clear in previous comment. I thought if you also specified which folders to place those xml and compiled classes then one would have a complete example of developing and deploying. I guess your audience was not novice like me. I like the example and style of this blog http://bushorn.com/simple-jms-use-case-on-wso2-esb/
LikeLike
Thanks for the links, I am already familiar with those. My bad if I wasn’t clear in previous comment. I thought if you also specified which folders to place those xml and compiled classes then one would have a complete example of developing and deploying. I guess your audience was not novice like me. I like the example and style of this blog http://bushorn.com/simple-jms-use-case-on-wso2-esb/
LikeLike
Can you provide steps to create a project for above java class. That will be help full for the novice developer like me.
LikeLike