Here is an example that proves my fear. The test failed.

package camelinaction;

import junit.framework.Assert;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.dataset.DataSet;
import org.apache.camel.component.dataset.DataSetEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.SimpleRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author txphh
 */
public class LoopTest {
    private final IntegerHolder initialValue  = new IntegerHolder(100);
    private CamelContext camelContext;
    private SimpleRegistry registry = new SimpleRegistry();
    private static Logger logger = LoggerFactory.getLogger(LoopTest.class);

    // //////////////////////////////////////////////////////////////
    public static class IntegerHolder {
        private Integer val = null;

        public IntegerHolder(Integer val) {
            this.val = val;
        }

        public void set(Integer val) {
            this.val = val;
        }

        public Integer get() {
            return this.val;
        }

        public void inc() {
            this.val++;
        }

        public void dec() {
            this.val--;
        }
    }

    // //////////////////////////////////////////////////////////////
    public static class DummyDataSet implements DataSet {

        @Override
        public void assertMessageExpected(DataSetEndpoint endpoint,
Exchange expected, Exchange actual,
                long messageIndex) throws Exception {
        }

        @Override
        public long getReportCount() {
            return 1;
        }

        @Override
        public long getSize() {
            return 1;
        }

        @Override
        public void populateMessage(Exchange exchange, long
messageIndex) throws Exception {
        }
    }

    @Before
    public void init() {
        camelContext = new DefaultCamelContext(registry);
        camelContext.setTracing(false);
        registry.put("dummy-dataset", new DummyDataSet());
    }

    @After
    public void tearDown() {
        try {
            camelContext.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // //////////////////////////////////////////////////////////////
    private Processor getLoopCountProcessor(final IntegerHolder loopCounter) {
        return new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                logger.info("in loop");
                loopCounter.inc();
                logger.info("loopCount is now: {}", loopCounter.get());
            }
           };
    }

    // //////////////////////////////////////////////////////////////
    private Processor getStopLoopProcessor () {
        return new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                logger.info("set header STOP_FLAG to true to stop the loop");
                // would like to stop here
                exchange.getIn().setHeader("STOP_FLAG", Boolean.TRUE);
            }
        };
    }

    // //////////////////////////////////////////////////////////////
    @Test
    public void doIt() throws Exception {

        final IntegerHolder loopCount = new IntegerHolder(0);
        camelContext.addRoutes(new RouteBuilder() {

            @Override
            public void configure() throws Exception {

                from("dataset:dummy-dataset")

                .log(LoggingLevel.INFO, "loop for:" + initialValue.get())

                .loop(initialValue.get())
                   .process (getLoopCountProcessor(loopCount))
                   .choice()

.when(header("STOP_FLAG").isNotEqualTo(Boolean.TRUE))
                      .process(getStopLoopProcessor())
                   .otherwise()
                     .log(LoggingLevel.INFO, "we are going to break
the loop")
                     .stop()
                   .end()
                .end()

                .log(LoggingLevel.INFO, "exit loop")
                .process(getLoopCountProcessor(loopCount))
                .to("mock:result")
                .log(LoggingLevel.INFO, "end route");

            }
        });

        camelContext.start();
        Thread.sleep(10000);
        Assert.assertEquals(new Integer(3), loopCount.get());
    }
}


2012/5/1, Hoang-Vu PHUNG <hvu.ph...@gmail.com>:
> Thanks a lot Claus,
>
> I'm afraid that calling stop will stopping complete the processing.
> Basically what i want is to construct a route with a loop in the middle.
> Under some circonstances I have to exit early the loop (basically simulate
> the while) and continue the route.
>
> Regards,
> Vu
>
> 2012/4/30 Claus Ibsen <claus.ib...@gmail.com>
>
>> On Mon, Apr 30, 2012 at 5:03 PM, Hoang-Vu PHUNG <hvu.ph...@gmail.com>
>> wrote:
>> > ---------- Forwarded message ----------
>> > From: Hoang-Vu PHUNG <hvu.ph...@gmail.com>
>> > Date: 2012/4/30
>> > Subject: Question regarding loop in camel
>> > To: users-h...@camel.apache.org
>> >
>> >
>> > Hi all,
>> >
>> > So far the loop construction in camel has a fixed number of iterations.
>> > Is it possible some how to :
>> >
>> > 1. dynamically change the count of interations
>>
>> No
>>
>> > 2. or exit the loop earlier
>>
>> Yes using stop. See the StopProcessor source code
>>
>> > 3. or better use a Predicate that is re-evaluated to decide to continue
>> to
>> > iterate or not ?
>> >
>>
>> There is a JIRA to make the loop like a while loop so we can use a
>> predicate to know if we should continue looping or not.
>> So someday in a future Camel release you can do it.
>>
>> > My project is to use camel to simulate a process workflow. I prefer
>> > camel
>> > because of its simplicity of usage.
>> > My only problem is how to simulate a while loop. I can do something
>> > like
>> > fixing a high number of iterations and then use a choice condition to
>> > decide to execute the process but we waste the resources unnecessarily.
>> >
>> > Thanks for your answer.
>> > Regards,
>> > Hoang-Vu
>>
>>
>>
>> --
>> Claus Ibsen
>> -----------------
>> CamelOne 2012 Conference, May 15-16, 2012: http://camelone.com
>> FuseSource
>> Email: cib...@fusesource.com
>> Web: http://fusesource.com
>> Twitter: davsclaus, fusenews
>> Blog: http://davsclaus.blogspot.com/
>> Author of Camel in Action: http://www.manning.com/ibsen/
>>
>

Reply via email to