Skip to content
Advertisement

Apache Camel: access Route after polling

I’m using Camel JPA endpoints to poll a database and copy the data to a second one. To not poll duplicates, I’m planning to save the highest ID of the copied data and only poll data with an ID higher than that one.

To save a few database writes, I want to write back the highest ID after the current polling / copying run is over, not for every single data element. I can access the element (and its ID) in the Camel Route class:

    private Long startId = 0L;
    private Long lastId = 0L;

    from("jpa://Data").routeId("dataRoute")
        .onCompletion().onCompleteOnly().process(ex -> {
            if (lastId > startId) {
                startId = lastId;
                logger.info("New highest ID: {}", startId);
            }
        }).end()
        .process(ex -> {
            Data data = ex.getIn().getBody(Data.class);
            lastId = data.getId();
            NewData newData = (NewData) convertData(data);
            ex.getMessage().setBody(newData);
        }).to("jpa://NewData")

Now I want to save startId after the current polling is over. To do so, I overrode the PollingConsumerPollStrategy with my custom one where I want to access lastId inside the commit method (which gets executed exactly when I want it to, after the current polling is complete).

However, I can’t access the route there. I tried via the route ID:

    @Override
    public void commit(Consumer consumer, Endpoint endpoint, int polledMessages) {
        var route = (MyRoute) endpoint.getCamelContext().getRoute("dataRoute");
        var lastId = route.getLastId();
        log.debug("LastID: {}", lastId);
    }

However I’m getting a class cast exception: DefaultRoute to MyRoute. Is it something about handing the ID to my route?

Advertisement

Answer

I would do it a bit differently.

Instead of using RouteBuilder instance vars for storing startId and lastId, you may also put these values as GlobalOptions (which is basically a map of key-value pairs) of current CamelContext.

This way, you can easily obtain their value using:

public void commit(Consumer consumer, Endpoint endpoint, int polledMessages) {
    String lastId = endpoint.getCamelContext().getGlobalOption​("lastId"); 
}

It is also (theoretically) a better implementation because it also supports potential concurrent executions, as the id are shared for all instances running in the context.

9 People found this is helpful
Advertisement