Currently I have a yaml file which includes different states in the Step function that runs different checks and returns pass or fail output
code Snippet:
Comment: Check all steps
StartAt: Check A
States:
Check A:
Comment: Verifies that A is done
Resource: "arn:aws:lambda:us-east-1:123456789012:function:checkA",
Next: Check B
Check B:
Comment:Verifies that B is done
Resource: "arn:aws:lambda:us-east-1:123456789012:function:checkB"
Next: Check C
Check C:
Comment:Verifies that C is done
Resource: "arn:aws:lambda:us-east-1:123456789012:function:checkC"
ResultPath: "$.ValidatedResults"
End: true
How can I modify this step function to accept an input map such that it only executes those States with boolean true
"OnlyVerify": {
"Check A": true,
"Check B": false
"Check C": true
}
And if OnlyVerify map is not specified as input to the Step function, it should run all the Checks.(True for all checks by default)
Expected Output
{
"OnlyVerify": {
"Check A": true,
"Check B": false
"Check C": true
},
"ValidatedResults": {
"Check A": PASS,
"Check C": PASS
}
}
Appreciate any guidance here
I would suggest playing with the logic a bit in the Workflow Studio, but something like this should get you most of the way there:
If the lambda function used to do the checking can be refactored to handle any of [A, B, C, ...] then that would enable making the step function definition much "cleaner" by leveraging a Map State, rather than a parallel state.
Related
I am creating a step function and there is a condition like this
if my step output is "is_query" : True then I have to move a different step and if false then I have to go to diffrent step I am following this example https://docs.aws.amazon.com/cdk/api/v1/python/aws_cdk.aws_stepfunctions/README.html
I got idea from this like this :
for example If I do something like this :
sfn_step_1.next(sfn_step_2).next(sfn.Choice(self, "Job Complete?").when(sfn.Condition.string_equals("$.is_query", "True"), sfn_special_step ).when(sfn.Condition.string_equals("$.is_query", "False"), Do Nothing ).next(sfn_step_3)
So I have 2 questions how I can make this Do Nothing and move to step 3 as at the end I want both to go to step 3 . just a extra step in is_query to True case. And 2nd question how I can add "is_query", "True" to payload for now my step 2 payload look like this :
sfn_step_2 = tasks.LambdaInvoke(self, "check-status",
lambda_function=check_status_lambda,
output_path="$.Payload",
integration_pattern=stepfunctions.IntegrationPattern.WAIT_FOR_TASK_TOKEN,
payload=stepfunctions.TaskInput.from_object({
"payload.$": "$",
"execution_id.$": "$$.Execution.Id",
"taskToken": stepfunctions.JsonPath.task_token
})
)
Instead of the second condition just add
.afterwards()).next(your next step)
this will solve both problems.
on your code is like this:
sfn_step_1.next(sfn_step_2).next(sfn.Choice(self, "Job Complete?").when(sfn.Condition.string_equals("$.is_query", "True"), sfn_special_step ).afterwards()).next(sfn_step_3)
In the following code, if documentDetails is available in payload of the step function for step Read, then only documentDetails variable be considered, otherwise it shouldn't be. documentDetails is optional and it may or may not be there in payload.
const readStep = new tasks.LambdaInvoke(this, 'Read', {
lambdaFunction: stepfLambda,
resultSelector: {
"s3Url.$": "$.Payload.s3Url",
"documentDetails.$": // present only if documentDetails is present in Payload
},
resultPath: '$.stepEventMetaData'
});
What is the correct syntax for the same?
resultSelector cannot apply conditional logic. Your best option is to have stepfLambda return the output in the desired shape.
I have a 3 step state machine for a step function.
InputStep -> ExecuteSparkJob -> OutputLambda
ExecuteSparkJob is a glue task. Since it cannot pass its output to the step function, it writes it output to an S3 bucket. OutputLambda reads it from there and passes it on to the step function.
The idea of InputStep is simply to define a common S3 URI that the following steps can use.
Below is the code I have for the Input Step.
const op1 = Data.stringAt("$.op1");
const op2 = Data.stringAt("$.op2");
const inputTask = new Pass(this, "Input Step", {
result: Result.fromString(this.getURI(op1, op2)),
resultPath: "$.s3path"
});
getURI(op1: string, op2: string): string {
return op1.concat("/").concat(op2).concat("/").concat("response");
}
However, the string manipulation that I am doing in getURI is not working. The values in inputTask.result are not being substituted by the value in Path.
This is the input and output to the Input Step
{
"op1": "test1",
"op2": "test2"
}
Output
{
"op1": "test1",
"op2": "test2"
"responsePath": "$.op1/$.op2/response"
}
Is it possible to do some string manipulations using parameters in the Path in Step Function definition? If yes, what am I missing?
Thanks for your help.
You can use one or more EvaluateExpression Tasks - it's still a bit clunky.
You can find examples here.
API doc here.
Use a Lambda function instead of a Pass state to build the string.
Step Functions doesn't currently support string concatenation with reference paths. The Result field of a Pass state doesn't allow reference paths either. It has to be static value.
The Pass state's Parameters field supports the intrinsic functions and substitutions you need to do this natively, without a Lambda task. The Result field doesn't.
Compose a string from the execution inputs with the Format intrinsic function:
const inputTask = new Pass(this, "Input Step", {
parameters: {
path: JsonPath.format(
"{}/{}/response",
JsonPath.stringAt("$.op1"),
JsonPath.stringAt("$.op2")
),
},
outputPath: "$.s3",
});
The resulting string value test1/test2/response will be output to $.s3.path.
I'm experiencing some troubles with my program.
I have a process that calls a function (Take_Job) that is supposed to remain blocked until a time (MINIMUM_WAIT) passes. If it doesn't happen that way, a message informing of this situation will appear.
for Printer_Id in Type_Printer_Id loop
select
delay MINIMUM_WAIT
Pragma_Assert (True, "");
then abort
Take_Job (Controller,
Printer_Id,
Max_Tonner,
Job,
Change_Tonner);
Pragma_Assert
(False,
"Testing of Take_Job hasn't been successful. It should have remained blocked.");
end select;
end loop;
The function Take_Job calls to an entry in a protected object:
procedure Take_Job (R : in out Controller_Type;
Printer : in Type_Printer_Id;
Siz : in Typo_Volume;
Job : out Typo_Job;
Excep_Tonner : out Boolean) is
begin
R.Take_Job(Printer, Siz, Job, Excep_Tonner);
end Take_Job;
Where "R" is the protected object.
The following code is the entry of the protected object. Actually, the "when" condition is True because I need to check some stuff with the parameters of the entry. Since Ada doesn't allow me to do that, I copy the parameters inside the protected object and call to a "delayed entry", then in the "delayed entry" I will make sure that the condition is met before proceeding.
entry Take_Job(Printer_Id: in Type_Printer_Id; Remaining: in Type_Volume; Job: out Type_Job; exceptionTonner: out Boolean)
when True is
begin
Copy_Remaining(Printer_Id) := Remaining;
requeue Take_Job_Delayed(Printer_Id);
end Take_Job;
Let's see the "delayed entry" code:
entry Take_Job_Delayed(for J in Type_Printer_Id)(Printer_Id: in Type_Printer_Id; Remaining: in Type_Volume; Job: out Type_Job; exceptionTonner: out Boolean)
when False is -- I've done this on purpose
begin
null; -- Actually, there would be a lot of code here
end Take_Job_Delayed;
Let's say that my goal is to pass the MINIMUM_WAIT and run the "Pragma_Assert(True, "")". If I put the "when" condition of Take_Job to "False", then everything works fine. Take_Job is never accepted and the Pragma_Assert will be executed. If I set it to "True" and the "when" condition of Take_Job_Delayed to "False", I don't get the same effect and the process gets blocked and neither of the Pragma_Asserts will be executed.
Why? It looks like the problem is in the "requeue" or somewhere near that, but why is this happening?
You need to do the requeue with abort;
entry Take_Job(Printer_Id: in Type_Printer_Id;
Remaining: in Type_Volume;
Job: out Type_Job;
exceptionTonner: out Boolean)
when True is
begin
Copy_Remaining(Printer_Id) := Remaining;
requeue Take_Job_Delayed(Printer_Id) with abort;
end Take_Job;
because otherwise the opportunity to abort the entry call has been lost. There are details in ARM 9.5.4, and a more understandable explanation in Burns & Wellings, “Concurrency in Ada”.
I am using dockyard/ember-validation to validate controller properties, but I haven;t been able to get it working as I expected it to. So I have basically toggle effect on checkboxes, and I have defined 2 validation rules and only one of them should be executed/validated when user toggles between the checkboxes.
My validation rules are defined as :
validations: {
"instructions": {
format: {
if: 'inlineSource',
'with': /^(?!\s*$).+/
}
},
"externalSourceValue": {
format: {
if: 'externalSource',
'with': /^(?!\s*$).+/
}
}
}
Here either inlineSource is true or externalSource is true, but both will never be simultaneously true. I would expect only one validation rule to be exercised, but it seems both are getting run disregarding the if condition there.
Here is the jsbin to the issue: http://jsbin.com/ODAmukOM/1/
Follow these steps :
1) click on External Website
2) set the input field value to empty
3) click to Content I Specify
4) the validation sets the controller to invalid state
Thanks,
Dee
you are adding 2 format validations,
instructions is valid if inlineSource && /^(?!\s*$).+/
really your logic needs to be more like this
"instructions": {
format: {
if: function(object, validator) {
console.log('inlineSource',object);
if(!object.get('inlineSource')){
return (object.get('instruction') || '').match(/^(?!\s*$).+/);
}
return true;
}
}
}
unfortunately validation is only run when you change properties, so you change instruction validation is run and it's invalid, you then switch (flipping inlineSource), but validation won't happen again. At this point you'll need to manually run validations to get that validation checked again. good luck