Exit from Apache Camel loop - apache-camel

I want to exit from Camel Loop at some condition. I am using Camel 2.15
.loop(simple("${exchangeProperty.loopCount}"))
.to("bean:xxx?method=exitFromLoop")
.end()
I tried changing CamelLoopIndex and CamelLoopSize in exitFromLoop method, but didn't worked for me.
Is there any alternative to this e.g using choice/when?

There is a loop while mode if you use Camel 2.17 onwards.
See the documentation: http://camel.apache.org/loop
Then the loop runs like a while loop until the predicate evaluates to false / null or zero.
As its a predicate it does not automatic decrement a counter, so its like a while loop in java.

Up to camel 2.16 (and in 2.17 as well) you can use a <camel:stop/> statement in a <camel:when> block inside the <camel:loop>, and set the loop counter to some arbitrary upper limit.
Alternatively your loop may contain a java processor that can conditionally stop the route with: exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);

Related

Start next Loop Controller iteration

I would like to configure something similar to Action to be taken after a Sampler error in Thread Group but at Loop Controller level.
For example, if one Sampler fails, instead of Start Next Thread Loop, I would like to Start Next Loop Controller Loop, I assume this would be achievable using groovy + JMeter properties, but I cannot find the right way to do it.
Try Until Controller from this guy -- http://www.testautomationguru.com/jmeter-until-controller/.
This should help.
You can do this By using While Loop instead of Loop Controller Use While Controller
Set Action to be taken on sampler error to continue on thread group.
Initialize a counter and set its value to 1 using a beanshell sampler , Keep this sampler before while loop begins
Add the following code
vars.put("counter","1");
Add A while Loop and keep the set of samplers you want to run in loop.
Add the following condition to while loop
${__javaScript(parseInt(${counter})<=15,)}
here 15 represents the number of loops (Loop Count)
Add A beanshell post processor to your first sampler in while loop
and add the following code (To increment the counter value)
int counter = Integer.parseInt(vars.get("counter")) +1;
vars.put("counter",Integer.toString(counter));
Next samplers in While loop embed with an if condition
${JMeterThread.last_sample_ok}
As shown below You have to do this for each sampler as we may not know where the error occurs.
In My case i wanted to run the loop 15 times irrespective of errors , You can see its executed 15 times even after getting errors
For more information on While controller Follow this link..
Please let me know if it helps ..
The easiest way is using If Controller.
Add If Controller after sampler on failure of which you want to restart the loop
Put all requests which are "below" the If Controller to be children of the If Controller
Use ${JMeterThread.last_sample_ok} as the If Controller condition
That's it, now If Controller's children will be executed only if previous sampler is successful, otherwise it will be next Loop Controller iteration.
As you can see from the above demo Some Other Sampler was executed only when Some Sampler was successful.

Breakable loop in Scratch?

How do you make a breakable loop in Scratch? I'm using Scratch 2.0 and can't find any good way to make a loop breakable, from inside of the loop itself.
Disclaimer:
There is no perfect way to do it. If you can possibly stand this true fact then feel free to continue.
There are a few different ways you could do it.
With repeat until
The first and most simple one follows this:
But this isn't technically part of the script - it's just repeating until some value returns true.
With a custom block (stop this script)
In order to do it inside of the script, you'll need to use a sneaky little trick with custom blocks.
Create a custom block called whatever you want - but probably along the lines of "breakable loop". Inside of it, create this script:
By using stop script we are breaking out of the script that is currently running - which, according to Scratch, is the custom block.
See the result! (as scratchblocks)
With broadcast and wait
You could also use a broadcast-and-wait method, very similar to above:
Though I highly suggest you don't use this method, as if any other sprites have breakable loops you'll need to rename each one, which can be tedious after using a lot of loops in a lot of sprites!
(Note this bug has been fixed in version 442 of the editor and such the following no longer applies.)
Help! My project is lagging a bunch now!
As #foi has noticed, if your code must be run inside of a frame you probably checked run without screen refresh. Unfortunately, due to a bug in the Scratch player, this causes the program to essentially break after the stop this script block has been activated. How can you handle this?
It follows the same principle you use when you use a run without screen refresh custom block inside of a forever loop - the loop doesn't use screen refresh while the inside does, allowing for instant animations whether or not one is using turbo mode.
Here's an example - the image is really too long to be embedded, so see it here instead.
You can make a variable inside or outside of the repeat and make your script like this:
repeat until [[my variable] = [e.g: 1]]
your code
your code
your code
your code
end of repeat until
For a "repeat until" block the simplest way would be to "or" your normal until condition with the break condition in the until.
By adding an incremeting loop counter variable in the loop you can use a "repeat until" to replicate the function of a "repeat n times" block
By using a "repeat until" block with only your break condition you get the equivalent of a "forever" block
If you need another script/ sprite to trigger the break then a public variable will let you break the loop from anywhere and let a single condition break loops for different sprites.
I'd post an image of the blocks but this is my first reply and the site won't let me!
good luck
You can use these few ways to do it...
conditional loop
stop this script
if then else, in the else section, put nothing
I would prefer to use the first method, as it requires less blocks and for the first method, you can still add in code that will be executed after the loop has stopped executing.
You can make it repeat x times or make it have a certain point where it stops, such as another variable changing.
Otherwise, I don't think there is a wat to do that.
Use the repeat until block. Then put in an equals block or whatever into the boolean part. Then inside that repeat until block, put a stop this script block.
Hope this helps :D

Camel: is it possible to start a block in java DSL?

Through Googling and searching the Camel docs I have not found a way to start a block within a Camel multicast statement in Java DSL.
For example, what I imagine is something like this:
from("direct:dummy")
.multicast()
.begin().setHeader("A","toto").process(doSomething).end()
.begin().setHeader("A","titi").process(doSomethingElse).end()
;
Where the hypothetical "begin()" would start a block. Is there such a construct ? Is there any other way to do something like this ?
The alternative I'm using at the moment is defining one "direct" per block, but in some cases (just setting a header in particular), this makes the code harder to read.
In my example, the alternative would look like:
from("direct:dummy")
.multicast()
.to("direct:dummy.toto")
.to("direct:dummy.titi")
;
from("direct:dummy.toto")
.setHeader("A","toto")
.process(doSomething)
;
from("direct:dummy:titi")
.setHeader("A","titi")
.process(doSomethingElse)
;
Use .pipeline() instead of .begin() as your block

changing variables in loop in Jmeter

I have web request like this
Loop Controller(3)
moreSamples=true
startIndex=0
While Controller(${__javaScript(${moreSamples}==true)})
SOAP/XML-RPC Request(index=${startIndex})
Regular Expression Extractor(startIndex=newIndex,moreSamples=samples)
Now problem is I am not able to initialize moreSamples and startIndex in loop.
I tried two options:
Make moreSamples and startIndex as user defined variables. Now I am able to change their values using Regular Expression Extractor but not able to reinitialize them in outer loop using BeanShell PostProcessor like this:
vars.put("moreSamples","false")
vars.put("startIndex","0")
Make moreSamples and startIndex as User Parameters in preprocessor of of while loop but then I am not able to assign them values using Regular Expression Extractor.
Please suggest the mistakes or some new construct which can fit in.
Screenshot:
#bpsingh,
Can you do following things:
Add UserDefinedVariables on top of your Test Plan with two defined variables:
moreSamples, startIndex (like #ant suggested already)
Under the Download - PersistentSyncScope Sampler, you have two regular expression extractors in which I assume you want to extract some values and place it in these two variables from the above. Add BeanShellPostProcessor under the Download - PersistentSyncScope Sampler.
In BeanShellPostProcessor add following code:
vars.put("moreSamples","${REGEX_EXTRACT1}");
vars.put("startIndex","${REGEX_EXTRACT2}");
These two (moreSamples, startIndex) are global variables and changes on them should be visible outside of the loop.
Do you have to initialize them from the loop? How about adding those to User Defined Variables?
Or you can do it from your loop as well, the reason why it doesn't work for you is either the fact that you forgot to put the semi-colon ; after your expression(s) :
vars.put("moreSamples","false"); // ; <- was missing
vars.put("startIndex","0"); // ; <- was missing
I used BSF Sampler and it worked for me (don't forget to choose the language -> beanshell if you use this one). Here is my debug sampler (relevant part) :
START.HMS=101818
START.MS=1341821898080
START.YMD=20120709
TESTSTART.MS=1341822195274
moreSamples=false
startIndex=0
Update:
You need not to use both BSF Sampler and user defined variables. You can use either, and I see you have more user defined variables, no need for that. Have one of those at the start of your test. I'm still not clear what your problem is and what you're trying to achieve.
Actually problem here is I am using 2 loops and all answers don't take this properly into account.
Since pre/post processors are applied only to samplers not to loops there is no way to reinitialize the variables before while loop. Thus if I add initialize statements in preprocessor, loop run infinitely and if in postprocessor, it never executes. Only way to initialize is adding BSF sampler before while loop but that will spoil the reports as this sampler will also be recorded by listeners.
So only solution I found is run Download - PersistentSyncScope Sampler once and add BSF preprocessor with following scripts
vars.put("moreSamples","false");
vars.put("startIndex","0");
Now add while loop and add Download - PersistentSyncScope Sampler as its child.
That is the only solution till now. Thanks everyone to help me understand the problem.

Foreach Loop Microsoft SSIS - equivalent to break statement

Within a Foreach loop in SSIS is there a way that if a task fails you can break out of the loop to the next iteration?
I am looping over xml files and performing a lookup using values within this file, if the lookup doesn't return any values i'd like to report on this and then not perform any other tasks for this file. If there is no equivalent to a break statement how else can this be achieved?
You could also use a 'for' loop with a boolean condition such as looping while a variable is equal to true. Then when you want to break out of that loop, simply change the value of that variable to false and then you will break out of the loop.
Answering your question...a foreach loop, loops over a collection and other enumerable constructs so long as they exist to loop over. So you could either find a workaround, or just use a 'for' loop instead of a 'foreach' loop. That way you have more of a programming type control over the loop because you set the condition expression.
And yet another way would be to put a sequence container into your loop then put the conditional steps in the sequence container. Any decision that should 'continue' need only exit the sequence container.
Very simple to implement with all the control you could want including error trapping.
The lookup can redirect if there are no values returned, away from the successful flow.
You need the rest of your foreach loop to know there has been an error, so one way would be to set a package variable on error, just before you do the logging.
Then, in the 'success' arrow after your lookup you can change it to a conditional success, so that it only proceeds if the value of the variable is not the error value.
So I just had that problem and solved it by a) directing the failed task to a dummy task which did nothing and ended and b) setting the 'FORCEEXECUTIONRESULTS' to 'SUCCESS', which plowed through just the way I wanted it to.

Resources