1 Reply Latest reply on Sep 5, 2008 4:09 PM by mike_ap

    Smooks File Splitting

      I have a service that picks up a large file and uses a Smooks Action to split it into smaller messages that are sent to another service.

      Since the file is large, I use the Filename composer (org.jboss.soa.esb.listeners.gateway.LocalFileNameMessageComposer) on the listener and then use the FileToStream action (org.jboss.soa.esb.actions.converters.FileToStream) before I invoke the Smooks action.

      However, after the split, there is no way of correlating the split messages with their source files. I would like generate a file id before calling Smooks (or use the filename) and add it to each split message so that I can correlate them later.

      Any suggestions on how I can do this?

      Thank you

        • 1. Re: Smooks File Splitting

          Well, I did my homework and there are a few possibilities. Some of them better than others. I chose to use the Smooks ExecutionContext object.

          The JBoss SmooksAction does not give us access to the Smooks ExecutionContext object before filtering with Smooks. So we either need to create a custom JBossESB Action class or use Groovy. I decided to use Groovy... just because it's groovy (pun intended).

          I added this to my jboss-esb.xml:

           <action name="ParseInputStreamWithGroovySmooks" class="org.jboss.soa.esb.actions.scripting.GroovyActionProcessor">
           <property name="script" value="/scripts/parse_groovy_smooks.groovy" />
           </action>
          


          my parse_groovy_smooks.groovy looks like this (Some of the imports might be unnecessary):
          import org.milyn.Smooks;
          import org.milyn.SmooksException;
          import org.milyn.event.report.HtmlReportGenerator;
          import org.milyn.io.StreamUtils;
          import org.milyn.container.ExecutionContext;
          import org.milyn.javabean.BeanAccessor;
          import org.xml.sax.SAXException;
          
          import javax.xml.transform.stream.StreamSource;
          import javax.xml.transform.stream.StreamResult;
          import java.io.*;
          
           try {
           Smooks smooks = new Smooks("smooks-config.xml");
          
           //Our default body location contains the FileInputStream for the file we want to split.
           msgBody = message.body.get();
          
           ExecutionContext executionContext = smooks.createExecutionContext();
          
           //Bind the contents of the fileReferenceLocation in the ESB message to the fileReferenceId bean in Smooks.
           BeanAccessor.addBean(executionContext, "fileReferenceId", message.body.get("fileReferenceLocation"));
          
           //Note the null value. That's because we don't want to return anything from the call to Smooks.
           smooks.filter(new StreamSource(msgBody), null, executionContext);
          
           } catch (IOException e) {
           e.printStackTrace();
           }
          


          And in smooks-config.xml you can access "fileReferenceId" like this:
           <resource-config selector="csv-record">
           <resource>org.milyn.javabean.BeanPopulator</resource>
           <param name="beanId">splitFragment</param>
           <param name="beanClass">java.util.HashMap</param>
           <param name="bindings">
           <binding property="csv_field1" type="String" selector="csv_field1" />
           <binding property="csv_field2" type="String" selector="csv_field2" />
           <binding property="csv_field3" type="String" selector="csv_field3" />
           <binding property="csv_field4" type="String" selector="csv_field4" />
           <binding property="fileId" selector="${fileReferenceId}" />
           </param>
           </resource-config>