David
David

Reputation: 341

stop apache.camel route (RoutePolicy)

I have a Route like the following.

        SimpleScheduledRoutePolicy policy = new SimpleScheduledRoutePolicy();
    policy.setRouteStartDate(new Date());
    policy.setRouteStartRepeatInterval(1000);

    from("file:data/in")
            .routePolicy(policy)
            .to("direct:validateInput")
            .to("direct:changeInput")
            .to("file:data/out");

So the Route takes an file from the inputfolder every second. After some validation and changing it writes it out to an out folder.

Now I would like to be able to close the actual route at every point. So If some error happens at the direct route validateInput the following two parts should not be excecuted.

I could do this with some doTry() and doCatch() but this will look ugly and hard to read.

Question: is it somehow possible to stop on loop of the main route without stopping the route complete? Like this the actual file won't be printed to the outfolder but the file comming in 5 seconds can be processed in normal way.

Creating a new Process and stopping the main Route in a seperate Thread doesn't work.

  1. The file is still written into the date/out folder

  2. The route is stopped complet and won't take any files anymore.

Upvotes: 1

Views: 1306

Answers (4)

David
David

Reputation: 341

found an answer which is good. For all folks who find this question here an "complete" solution.

        public void start() {
    try {
        CamelContext camelContext = new DefaultCamelContext();
        camelContext.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                errorHandler(loggingErrorHandler().level(LoggingLevel.ERROR));

                SimpleScheduledRoutePolicy policy = new SimpleScheduledRoutePolicy();
                policy.setRouteStartDate(new Date());
                policy.setRouteStartRepeatInterval(1000);

                //Exception Handling in case the xsd validation fails
                onException(SomeSpecialException.class)
                        .log(LoggingLevel.ERROR, "${exception}")
                        .handled(true).useOriginalMessage()
                        .to("file:test-data/error?autoCreate=true")
                        .end();

                //start main route
                from("file:test-data/in?delete=true")
                        .routePolicy(policy)
                        .log(LoggingLevel.DEBUG, "Processing file ${file:name}")
                        .to("direct:validateInput")
                        .to("direct:validateContent")
                        .to("direct:validateOutput")
                        .to("file:test-data/out");

                //start of separate Routes
                from("direct:validateInput")
                        .doTry()
                        .to("validator:message.xsd")
                        .doCatch(ValidationException.class)
                        .process(getErrorProcess());

                //...
            }
        });
        camelContext.start();
    } catch (Exception e) {
        LOGGER.error("Error while processing camel route: " + e.getMessage());
    }
}

/**
 * throws an SomeSpecialException in case of calling
 *
 * @return a Processor which is supposed to be called in case an {@link org.apache.camel.ValidationException} happens
 */
private Processor getErrorProcess() {
    return new Processor() {
        @Override
        public void process(Exchange exchange) throws Exception {
            StringBuilder message = new StringBuilder();
            String fileContent = exchange.getIn().getBody(String.class);
            String originalErrorMessage;

            try {
                SchemaValidationException schemaValidationException = (SchemaValidationException) exchange.getProperties().get("CamelExceptionCaught");
                originalErrorMessage = schemaValidationException.getMessage();
            } catch (Exception e) {
                originalErrorMessage = "Could not retrieve original error message.";
            }
            message.append("Could not validate import against the xsd. ")
                    .append("Original message: ").append(originalErrorMessage).append("; ")
                    .append("File:").append(fileContent);

            throw new SomeSpecialException(message.toString());
        }
    };
}

Thanks for everyone that helped me.

Upvotes: 0

David
David

Reputation: 341

It works good, but 1 Problem is still left. My actual Example looks like the following:

                    SimpleScheduledRoutePolicy policy = new SimpleScheduledRoutePolicy();
                policy.setRouteStartDate(new Date());
                policy.setRouteStartRepeatInterval(1000);

                //start main route
                from("file:test-data/in?delete=true")
                        .routePolicy(policy)
                        .onException(Exception.class)
                        .log(LoggingLevel.ERROR, "${exception}")
                        .handled(true).useOriginalMessage()
                        .to("file://test-data/error?autoCreate=true")
                        .end()
                        .log(LoggingLevel.DEBUG, "Processing file ${file:name}")
                        .to("direct:validateInput")
                        .to("direct:validateContent")
                        .to("direct:validateOutput")
                        .to("file:test-data/out");



                from("direct:validateInput")
                        .doTry()
                        .to("validator:message.xsd")
                        .doCatch(ValidationException.class)
                        .process(getErrorProcessor("Could not validate import against the xsd. Message: ${exception}; File: ${body}"));

//...
    }
}

private Processor getErrorProcessor(final String message) {
    return new Processor() {
        @Override
        public void process(Exchange exchange) throws Exception {
            throw new Exception(message);
        }
    };
}

If I put an incorrect file into the in folder I get the following error message:

ERROR route1:145 - java.lang.Exception: Could not validate import against the xsd. Message: ${exception}; File: ${body}

As you can see, camel replaced the ${...} attribute one time. But after this I won't replace the new ${...} elements. Any Idear how I can tell camel replace any new {...} parts or how I can replace them before by my self?

Upvotes: 0

Ben ODay
Ben ODay

Reputation: 21005

just have your validateInput step throw an Exception and use an onException() clause to handle the exception, that will short-circuit the flow for just that message and allow for processing future files dropped into the 'data/in' directory normally

Upvotes: 1

nerdyoutdoorsman
nerdyoutdoorsman

Reputation: 134

I believe you best option is using doCatch and doFinally. I think anything different would be much more difficult to read and very ugly.

http://camel.apache.org/validation.html

This is the most logical approach to solving this problem.

Upvotes: 0

Related Questions