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 <[email protected]>:
> 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 <[email protected]>
>
>> On Mon, Apr 30, 2012 at 5:03 PM, Hoang-Vu PHUNG <[email protected]>
>> wrote:
>> > ---------- Forwarded message ----------
>> > From: Hoang-Vu PHUNG <[email protected]>
>> > Date: 2012/4/30
>> > Subject: Question regarding loop in camel
>> > To: [email protected]
>> >
>> >
>> > 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: [email protected]
>> Web: http://fusesource.com
>> Twitter: davsclaus, fusenews
>> Blog: http://davsclaus.blogspot.com/
>> Author of Camel in Action: http://www.manning.com/ibsen/
>>
>