Search code examples
javaspringapache-cameldataformatbean-io

Marshalling from data object results in empty file


In one of our legacy applications we would create data objects that contained data from our SQL tables, and then we would marshal them with the Apache Camel routes in XML DSL and the BeanIO formatting library. This worked fine. In our new application I am trying to emulate the same behaviour, but with the Java DSL routing instead. I'm using Apache Camel 4.0.0, Spring 4.0.0, and BeanIO 3.4.0.

The routes look something like this:

BeanIODataFormat dataFormat = new BeanIODataFormat("path/beanioFormats/beanio_format.xml", "FormatSourceName");

from("{{cron.process}}")
        .log(LoggingLevel.INFO, "Creating File")
        .transform().method("fileGeneratorClass", "generatorMethod")
        .to("direct:marshalFile")
        .end();

from("direct:marshalFile")
        .marshal(dataFormat)
        .to("file:{{output.file.path}}")
        .end();

while the beanio format file looks very standard and similar to what we had before, like so:

<?xml version="1.0" encoding="UTF-8"?>

<beanio xmlns="http://www.beanio.org/2012/03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">

    <stream name="FormatSourceName" format="fixedlength">

        <group name="fileWrapperObject" class="path.to.wrapper.class">
            <record name="fileHeader" class="path.to.header.class" minOccurs="1" maxOccurs="1">
                <field name="fileRecordIdentifier" rid="true" length="3" required="true" literal="000"/>
            </record>
    ... etc

and finally, the generatorMethod that sets the data object into the exchange is as such:

    public void generatorMethod(Exchange exchange) {

        FileWrapperObject fileWrapperObject = new fileWrapperObject();

        // fill it with data

        LOG.info("Wrapper object created");

        exchange.getIn().setBody(wrapper);

        String fileName = "fileName";
        exchange.getIn().setHeader(Exchange.FILE_NAME, fileName);
    }

I'm certain the data object is not null nor are any of its fields, but the resulting file is always empty. Any clue on where I went wrong? My gut says it's the way I've written the marshalling in the routes file, but I'm not sure where to proceed, given the BeanIO documentation is rather bereft.

The main difference I see in the XML DSL based approach is that the dataFormats would be defined in the <camelContext> and then be accessed by ID, but to me, what I have written seems correct.


Solution

  • I ended up using the BeanWriter class provided by the BeanIO library to marshal to an output file, although from my processor method instead of from my routes. I essentially copied the documentation here regarding marshalling: https://beanio.github.io/docs/