StepContribution or ChunkContext for ExecutionContext info - spring-batch

In a Spring Batch tasklet execute(StepContribution stepContribution, ChunkContext chunkContext) method in a step that encrypts a file after the file has been written by previous steps, I need to access information in the job ExecutionContext. It looks like I can get that information from either the stepContribution:
stepContribution.getStepExecution().getJobExecution().getExecutionContext()
or the chunkContext:
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().
Will that always be the case? Or are there cases where the stepContribution will have a reference to the execution context but the chunkContext will be null or where there could be some other relevant difference between the chunkContext and the stepContribution?

The job execution reference will always be the same whether you access it from the chunk context or from the step contribution.

Related

Kafka Streams: How to stop stream application when exception

Version 1.0
Let's say in the punctuate method of lowlevel processor, creation of a dummy file fails with an exception. How to stop the stream application when an exception is encountered?
I was wondering if there is a way to throw an exception, but could not add throw clause on the init method. The following requires to be surrounded by a try-catch OR an exception to be thrown and can't use either one. Please suggest.
Files.createFile(Paths.get(dummyFile));
you could wrap IOException into any unchecked exception like RuntimeException, or would be better to create your own that will extend from RuntimeException, and throw it. if your method throw exception for any incoming message, stream will be in a dead state, so stop consuming messages until you restart application

What does the Wait operator in Rx.NET do?

In v2.2.5 of the Rx.NET library, there is an operator named Waitthat is defined as so:
public virtual TSource Wait<TSource>(IObservable<TSource> source)
Neither the class library reference on MSDN nor this page mention this operator.
From looking at its implementation, which is a bit too cumbersome to follow, I am guessing it waits for the observable to produce all its elements and returns the last element if the observable had any elements, and if not, it returns the default(TSource). But I am not sure.
If this is correct, then how is it different from LastOrDefaultAsync?
What does it actually do?
The intellisense documentation seems pretty accurate
Waits for the observable sequence to complete and returns the last element of the sequence.
If the sequence terminates with an OnError notification, the exception is thrown.
https://github.com/Reactive-Extensions/Rx.NET/blob/master/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs#L493
So the operator will block the calling thread (YUCK!) until the sequence completes and then yield the last value.
LastOrDefaultAsync in contrast returns an IObservable<T> so is not blocking.
The documentation for the methods are on the Observable class, not the query language implementation.
Waits for the observable sequence to complete and returns the last element of the sequence.
If the sequence terminates with an OnError notification, the exception is throw.
https://github.com/Reactive-Extensions/Rx.NET/blob/v2.2.5/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs#L493
It's essentially a synonym of Last<TSource>().
Wait
Last
The description of Wait provided in the question is not fully correct.
Here are the similarities between Wait and LastOrDefaultAsync:
Both logically wait to receive all the values in the source observable. But as Lee Cambell points out in his answer, Wait blocks the current thread while LastOrDefaultAsync does not.
Here is the summary of differences between Wait and LastOrDefaultAsync:
If there are no elements in the observable sequence, Wait throws an exception; LastOrDefault returns default(TSource).
If an exception occurs during the observation of the observable, Wait reports the exception by invoking observer.OnError but then also throws the exception immediately afterwards; LastOrDefaultAsync only reports the exception by calling observer.OnError on all subscribed observers. However, on error, in both the cases, the observation is stopped.
The XML documentation that comes with the source code (or even with the binary distribution either via NuGet or through the MSI installer) for Rx explains thus:
Waits for the observable sequence to complete and returns the last
element of the sequence. If the sequence terminates with an OnError
notification, the exception is throw.
Exceptions
Throws ArgumentNullException if source is null.
Throws InvalidOperationException if the source sequence is empty.

Exception handling in drools statefullSession

I'm not sure what is the correct way of handling exceptions in RHS of rules.
I've a statefullSession (drools version 5.5) that keeps firing until halt gets called i.e.
Runnable firingTask = new Runnable() {
public void run() {
ksession.fireUntilHalt();
};
taskExecutor.execute(firingTask);
The problem is that some parts of my code that gets called as a part of consequence section might throw an exception. If that happens no furher activations happen
My question is:
Is there any correct way how application exception should be propagated back to drools? Or is it that any RHS code has to be run inside try/catch block and these exceptions should be propagated as some additional facts into session?
The general strategies for exception handling apply here as well: just consider a consequence as being a static method that is being called due to the fireUntilHalt.
If the exception should or must be handled in the context of the RHS code, you'll have to use a try-catch statement. Otherwise, the exception is propagated and the remainder of the RHS code will not be executed. (This may include the omission of some essential statement such as a modify or insert or retract, which may affect the progress of the session.)
If you catch the exception org.drools.runtime.rule.ConsequenceException in a try around the fireUntilHalt, you can call fireUntilHalt again. The remarks from the previous paragraph apply here as well.
How you log an exception is completely up to you, but inserting Exception objects as facts (and writing rules to reason over them?) seems rather unconventional.

Execute batch job (JSR 352) on startup

I have a batchjob and need to run it up the application. He makes the call for the job, but the job does not reach the method.
BatchRuntime.getJobOperator().start(JOB_NAME, new Properties());
Throws no errors. So it seems that he is looking for the resource that indicates which class Implementing this job, but not yet loaded. Any idea?
The start() method is asynch so the caller isn't going to always see exceptions on failure.
Is the XML corresponding to JOB_NAME found? Any errors in the logs?

Accessing the process instance from Rule Tasks in JBPM 5

The short version: How do I get JBPM5 Rule Nodes to use a DRL file which reads and updates process variables?
The long version:
I have a process definition, being run under JBPM5. The start of this process looks something like this:
[Start] ---> [Rule Node] ---> [Gateway (Diverge)] ... etc
The gateway uses constraints on a variable named 'isValid'.
My Rule Node is pointing to the RuleFlowGroup 'validate', which contains only one rule:
rule "Example validation rule"
ruleflow-group "validate"
when
processInstance : WorkflowProcessInstance()
then
processInstance.setVariable("isValid", new Boolean(false));
end
So, by my logic, if this is getting correctly processed then the gateway should always follow the "false" path.
In my Java code, I have something like the following:
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("myProcess.bpmn"), ResourceType.BPMN2);
kbuilder.add(ResourceFactory.newClassPathResource("myRules.drl"), ResourceType.DRL);
KnowledgeBase kbase = kbuilder.newKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
new Thread(new Runnable()
{
public void run()
{
ksession.fireUntilHalt();
}
}).start();
// start a new process instance
Map<String, Object> params = new HashMap<String, Object>();
params.put("isValid", true);
ksession.startProcess("test.processesdefinition.myProcess", params);
I can confirm the following:
The drl file is getting loaded into working memory, because when I put syntax errors in the file then I get errors.
If I include a value for "isValid" in the Java params map, the process only ever follows the path specified by Java, apparently ignoring the drools rule.
If I take the "isValid" parameter out of the params map, I get a runtime error.
From this I assume that the final "setVariable" line in the rule is either not executing, or is updating the wrong thing.
I think my issue is related to this statement in the official documentation:
Rule constraints do not have direct access to variables defined inside the process. It is
however possible to refer to the current process instance inside a rule constraint, by adding
the process instance to the Working Memory and matching for the process instance in your
rule constraint. We have added special logic to make sure that a variable processInstance of
type WorkflowProcessInstance will only match to the current process instance and not to other
process instances in the Working Memory. Note that you are however responsible yourself to
insert the process instance into the session and, possibly, to update it, for example, using Java
code or an on-entry or on-exit or explicit action in your process.
However I cannot figure out how to do what is described here. How do I add the process instance into working memory in a way that would make it accessible to this first Rule Node? Rule Nodes do not seem to support on-entry behaviors, and I can't add it to the Java code because the process could very easily complete execution of the rules node before the working memory has been updated to include the process.
As you mentioned, there are several options to inserting the process instance into the working memory:
- inserting it after calling startProcess()
- using an action script to insert it (using "insert(kcontext.getProcessInstance()")
If calling startProcess() might already have gone over the rule task (which is probably the case in your example), and you don't have another node in front of your rule task where you could just use an on-entry/exit script to do this (so that's is hidden), I would recommend using an explicit script task before your rule task to do this.
Kris