Search code examples
apache-camelsftpioexceptiononexception

Camel SFTP Route fails to continue onException


I've fairly simple looking route

sftp://hostname:22//incoming/folder/location/?username=username&password=xxxxx
&localWorkDirectory=/tmp&readLock=changed&readLockCheckInterval=2000
&move=processed/$simple{date:now:yyyy}/$simple{date:now:MM}/$simple{date:now:dd}${file:name}
&consumer.delay=450000&stepwise=false&streamDownload=true&disconnect=true

I also have an onException clause

onException(ValidationException.class)
            .handled(true)
            .logStackTrace(true)
            .filter(header("VALIDATION_ERROR").isEqualTo(true))
            .choice()
              .when(header("CamelFileName").contains("Param1"))
               .to(sftp://hostname:22//One/error/folder?password=xxxxxx&username=username)
              .when(header("CamelFileName").contains("Param2"))             
               .to(sftp://hostname:22//Two/error/folder?password=xxxxxx&username=username)
            .endChoice();

When I have single file, the route seems to work as expected. When more than one file and exception occurs, I get many different exceptions like

org.apache.camel.component.file.GenericFileOperationFailedException: Cannot list directory: incoming/folder/location

Caused by: java.lang.IndexOutOfBoundsException

I tried using all the attributes mentioned in the route viz. streamDownload, stepwise, readLock, localWorkDirectory et al. However, the error handling while multiple files is not working. I see the first file getting processed. However, it doesn't move to the processed folder once the exception occurs and then incoming/folder/location becomes non listable. I tried using continued(true) as well instead of handled(true)


Solution

  • The problem was with multiple files being handled in the same exchange. On exception, the route was trying to FTP back the error file on the same server. The solution was to split body into multiple exchanges so that each file has its own exchange and process them separately.

    from(sftp://hostname:22//incoming/folder/location/?username=username&password=xxxxx
    &localWorkDirectory=/tmp&readLock=changed&disconnect=true&stepwise=false
    &move=processed/$simple{date:now:yyyy}/$simple{date:now:MM}/$simple{date:now:dd}${file:name}
    &consumer.delay=450000).split(body()).processRef("incomingProcessor").end();