Siddharth Siddharth - 10 days ago 6
Apache Configuration Question

Apache Camel - File Transfer on Particular Route Call

I'm trying to create a webservice which, when called look into a local directory picks up files from there and upload to the ftp server.

I'm able to create a simple route which picks file from local directory and uploads to ftp server below is the code :

<route>
<from uri="file://D:\\FTPTest?noop=true&amp;delay=2000" />
<to uri="ftp://user@host.in:21/public_html/EnterpriseProject?password=password123#"/>
<to uri="bean:myBean?method=test" />
</route>


But, I want to this file transfer to be called when a particular route is called via restlet webservice is called, I tried with the following code, but it didn't work :

<route>
<from uri="direct:fileTransferRoute" />
<to uri="file://D:\\FTPTest?noop=true&amp;delay=2000" />
<to uri="ftp://user@host.in:21/public_html/EnterpriseProject?password=password123#"/>
</route>


The above route is called by restlet from following route :

<route>
<from
uri="restlet:http://0.0.0.0:9080/csitec/{serviceName}?restletMethod=post" />
<process ref="serviceRouteProcessor" />
<toD uri="direct:${in.header.nextRoute}" />

</route>


Here's the code of my serviceRouteProcessor :

public void process(Exchange exchange) throws Exception {
String body = exchange.getIn().getBody(String.class);
String serviceName = exchange.getIn().getHeader(Constants.SERVICE_NAME).toString();
String nextRoute = serviceName+Constants.NEXT_ROUTE_APPENDER;
exchange.getOut().setHeader(Constants.NEXT_ROUTE, nextRoute);
exchange.getOut().setBody(body);
}


Please help me and suggest the changes needs to be done to make it work like this.

Answer

Edited :

you must understand one thing first , to is producer not consumer <to uri="file://D:\\FTPTest?noop=true&amp;delay=2000" />

What you can do is ,

@Autowired
private CamelContext context;// if you have more than one camel context use @Qualifier and wire by bean id


public void process(Exchange exchange) throws Exception {
    String body = exchange.getIn().getBody(String.class);
    String serviceName = exchange.getIn().getHeader(Constants.SERVICE_NAME).toString();
    context.startRoute(serviceName+Constants.NEXT_ROUTE_APPENDER);// here in nextroute you must give the routeid
}

your route must look like

 <route id = "<value of serviceName+Constants.NEXT_ROUTE_APPENDER>" autoStartup = "false">
                <from uri="file://D:\\FTPTest..." />
                <onCompletion onFailureOnly="true">
                  <choice>
                    <when>
                        <simple>${property.CamelBatchComplete}</simple>
                    <process ref="asyncSelfShutdownProcessor"/>
                    </when>
                  </choice>
                </onCompletion>
                <to uri="ftp://user@host.in:21..."/>
            </route>

And add asyncSelfShutdownProcessor to spring context

@Component
public class AsyncSelfShutdownProcessor extends AsyncProcessor {

    @Autowired
    private CamelContext context

     public boolean process(Exchange exchange, AsyncCallback callback){

          new Thread(() -> context.stopRoute(exchange.getFromRouteId()).start();
     }
}

############################################################################## Old :

OK I understand your need as - you have a route that moves file from file system to ftp server, all you need is this route to get executed only when you trigger from a rest service. I would do it like this ,

*I will make the route autoStartup = "false" and assign as id = "fs-to-ftp" to the route

<route id = "fs-to-ftp" autoStartup = "false">
            <from uri="file://D:\\FTPTest..." />
            <onCompletion onFailureOnly="true">
                <process ref="asyncSelfShutdownProcessor"/>
            </onCompletion>
            <to uri="ftp://user@host.in:21..."/>
        </route>

**Add a self shutdown async process in onComplete to the route "fs-to-ftp". Async Processor

asyncSelfShutdownProcessor= AsyncProcessorConverterHelper.convert(exchange -> {
            new Thread(() -> context.stopRoute("fs-to-ftp")).start();
        });

***Add the camel context dependency to rest service and start the route by id in the rest service context.startRoute("fs-to-ftp")

Comments