How to perform a conditional test within a Talend job? - talend

I am looking to trigger a series of processes, and I want to tell if each one succeeds or fails before starting the subsequent ones.
I am using tSSH (on Talend 6.4.1) to trigger a process and I only want the job to continue if it is a success. The tSSH "component" doesn't appear to fail if it receives a non-zero return code, so I have tried using an assert. However, even if the assert fails, it doesn't appear to prevent the component and subjob being "OK" which is a bit odd, so I can't use on-(component|subjob)-ok to link to the next job.
I don't seem to be able to find any conditional evaluation components which will allow me to stop the continuation of the job or subjob based on the evaluation result.
The only way I can find is to have
tSSH1 --IF globalMap.get("tSSH_1_EXIT_CODE").equals(0)--> tSSH2...
--IF !globalMap.get("tSSH_1_EXIT_CODE").equals(0)--> (failure logging subjob)
which means coding the test twice with negation.
Am I missing something, or are there no such conditional components?

you can put a if condition on tSSH component for success /failure using global variable of tSSH component i.e.
((String)globalMap.get("tSSH_1_STDERR")) and ((String)globalMap.get("tSSH_1_STDOUT")).
if condition you can check is :
if(((String)globalMap.get("tSSH_1_STDERR")) != null) than call error log
else call tSSH2.
Hope this helps...

Related

Until flag not working with Until activity of ADF and loop keep going

I'm trying to execute Azure Durable Function in ADF.
I have "Get Current Function Status" Activity inside Until activity. Possible value are pending, completed, running and exception. I have variable until_flag which do get value "true" if runTimeStatus get value Completed.
My problem is that even runTimeStatus is completed Until loop never stop. It keeps going. What is wrong?
I'm following tutorial https://www.youtube.com/watch?v=aD3k8k5sdao
I have tried:
#equals(bool(variables('until_flag')), 'true')
and
#bool(variables('until_flag'))
If you look into the official MS docs on UntilActivity
Enter an expression that will be evaluated after all child activities
defined in the Until activity are executed. If the expression
evaluates to false, the Until activity will execute all its child
activities again. When it evaluates to true, the Until activity will
complete. The expression can be a literal string expression, or any
combination of dynamic expressions, functions, system variables, or
outputs from other activities.
So try with this expression to evaluate condition
#equals(variables('until_flag'), 'false')

How to setup a condition in anylogic, that will return true, only when specific message is received?

Good day,
I'm trying in AnyLogic to make block "Ped Select Output" (from Pedestrian library) select output based on the received message, using the command in conditions table receive("go");. This block is located in Main, while the message is supposed to be sent from the agent tab (MyAgent) using the command send("go", main.pedSource);. Yet if I try to launch this model I get the error "Type mismatch, cannot convert void to boolean". I believe I have incorrectly selected one of the commands (or maybe both), thus I hope for advice about it. Thanks in advance for the answer.
P.s. check screenshots, for more detailed information.
P.p.s. the model, that is presented on screenshots is just an oversimplified example of the real model (that's why 4 out of 5 outputs of the block are connected to one place).
main
agent
Each condition in the selectoutput should return a boolean... a boolean can be true or false
Some example of booleans are 3==2, 5>4, agent.priority==1, etc
These things are booleand because they are true or false
you are putting in the condition a function that doesn't return anything (receive) and I have absolutely no idea what is in your head that would suggest that this might work in any way...
I suggest you add a variable in your ped agent that defines what the pedestrian should do...

talend - retry subjob based on REST request results

I have a RESTful api I am trying to consume using talend
in order to get data 2 api calls are needed, the first generates an ID for your report, which you then use to make a consecutive api call using that ID to get your data results
the issue is if the requested report in the 2nd api call has not yet completed it will return
[{data:{string:"Requested report ### has not finished processing yet, please try again later"}}]
so, i put a tJava to thread(5000) to stagger the 1st api call (tRestClient2) from the 2nd api call (tRestClient1), but I could forsee this being an issue
what i want to do is evaluate the 2nd tRest request result (tFileOutputJSON_3), and if it equals "Requested report...", then requeue the 2nd tRest request until the data is ready
here is a screenshot of my job
Like always there is ton of solutions.
But you are not far from what you want. This following design should respect your expectation :
I kept your components as I don't really know what you are doing inside(I retired tLogrow to make things concise). But I reorganized scheduling links.
tJava
|onSubjobOk
tRestClient -- >
tFileOutputJSON
|onSubjobOk
tFileInputJSON-- >
tExtractJSONFields -- > tJavaRow
|onSubjobOk
tSetGlobalVar1
|onSubjobOk
tLoop2 -- iterate (order1)-- > tRestClient -- >
tHashOutput3
| -- iterate
(order2)-- > tHashInput4 -- > tJavaRow5
| -- iterate
(order3)-- > tSleep6
|onSubjobOk
tHashInput7 -- > tFileOutputJSON
1:Use a variable to manage the loop.
2:Use a While loop. Leave declaration and iteration blank (""), and put your condition using the previously initialized variable.3:Do not use Append as you want to fetch new result at each loop.
4:Link it to your HashOutput and do not clear cache.
5:Do your work here. Do not forget to update the global variable.
6:Can be placed before the call if most calls required time before report getting ready.
7:Link it to your HashOutput too, you will be able to fetch the data that made a end to the loop.

Exception when exiting

I'm writing a chef recipe as shown below. I hope the recipe can stop to continue executing the resources after this, but without giving the exception.
Do you have any ideas about this except from doing exit(0)?
ruby_block "verify #{current_container_name}" do
block do
require "docker"
begin
container = Docker::Container.get(current_container_name)
rescue Docker::Error::NotFoundError => exception
container = nil
end
if container.nil?
exit(0)
end
end
end
You could use ignore_failure true in this ruby block instead of handling the exception. That way it would still output the error messages, but wouldn't treat it as a failure so would continue to execute subsequent resources.
If you want to abort a chef-run under a special circumstance - like the current Docker-container is not available - this is not possible. The solution is to rethink your problem - you want some code to be only run when a special condition is met.
You do this by either leaving the recipe (with a return true), encapsulating your configuration steps in a conditional-clause (like a if my_container.nil? then ... end) or you use node-attributes to step through conditions.
Let's say your cookbook x relies on three recipes, 1, 2 and 3. So if you'd like to define that 2 and 3 are only run if 1 was successful, you're able to to write the state of the 1st recipe into the node-attributes (f.e. node.normal['recipe1'] = 'successful').
In the other recipes you'll then define an entry-gate like:
return true if node['recipe1'] != 'succesful'
But be aware, if you're using node-attributes you'll need to use the ruby_block-resource (mostly) at the end of your first recipe because the bare-ruby-code is evaluated and run during the resource-compilation - which takes place before the converge-run.

Skip a component based on condition in Talend

I have a scenario where I would like to skip a component to execute based on the condition and run its consecutive components in Talend.
Is it at all possible?
You have two options available to you for conditionally executing parts of your job.
Where the component that follows your conditional check can be a starting component (if you drop it to the canvas then it should have a green background) then you can use the Run if connector to link it to the previous part of your job like so:
In this example we simply call another tJava component conditionally but this could be any component that is startable.
Where the first tJava component (Set condition boolean) is configured with the following code:
Boolean condition = false;
globalMap.put("condition",condition);
And the two Run if connectors are set as ((Boolean)globalMap.get("condition")) == true and ((Boolean)globalMap.get("condition")) == false respectively.
A better option may be to use the filtering in a tMap or tFilterRow component and this also allows you to link to components that aren't starting components. To do this you would set your job up as below:
In this job I have hard coded some tabular data in a tFixedFlowInput component:
We then use a tMap to filter the flows of data to any following components:
In which we test the value of the boolean condition column of our data. As an illustration I have also applied some simple, conditional transformation to the data where "true" rows have 1000 added to their value and "false" rows have 100 subtracted from their value.
From here you can then carry on the flow of your job as normal, in this case we link to a tSystem component to execute system commands as per your comment.
I've mocked up a job for you:
I have a context variable called: startFrom
It can be accessed with context.startFrom
I've placed a tJava with a few tWarns:
I use 4 context settings:
Default
Normal
Opt
two
So my Job:
Does nothing
Start from "Start"
Start from "Optional_Start"
Start from "RecoverFromHere"
If settings are the following:
context.startFrom.equals("opt")
Recovery and Recovery1 prints out their names using System.out
If I start my job I can select where I want to start it. If I don't select anything: context value is null, it won't do anything.
you can not use prejob as it does not have runif trigger, but you can do like this
prejob -->oncomponentok-->tJava (in here you poupulate you evaluate your condition say as given below)---->RUN IF Trigger - you put your condition here..((String)globalMap.get("var_myCondition")).equals("true") --->component to run in true condition
--->RUN IF Trigger on (tJava) ---((String)globalMap.get("var_myCondition")).equals("false")--->component to run in false condition
in short your job would be like
prejob-->tJava---(RUNIF TRIGGER)------>component/flow to run in true condition
---(RUNIF TRIGGER)------>component/flow to run in false condition
tJava code
String myCondition="false";
globalMap.put("var_myCondition",myCondition);