VMware Cloud Community
ghaithsultaneh
Contributor
Contributor

Invoke VRO Workflow using Scriptable Task

Hi all,

I want to invoke a workflow using scriptable Task .

which script should i use to invoke the Workflow?

Thanks

0 Kudos
10 Replies
daphnissov
Immortal
Immortal

Please be more specific as to your use-case and what you're trying to accomplish. vRO already has schema objects to invoke nested workflows.

0 Kudos
ghaithsultaneh
Contributor
Contributor

I have a table in the Database with the following fields name : input , subworkflow. and the DB is  SQL plugin .

I want through scriptable Task to call a sub workflow depending on the input Value.

for example : if the input is 1 so it will take the associated id in the subworkflow field.

I did made read task from this Table and i binded the result as input to scriptable task .

and i wrote inside the scriptable task the following :

var subworkflowId = result.subWorkflow; // result is the output for read task and subWorkflow is the field name in the table

var workflowToExecute = System.getModule("com.vmware.library.workflow").getWorkflowById(subworkflowId);  // the id here is stored in the table in form of "1234452525"

var objWorkflowToken= workflowToExecute.execute();

the problem that i am facing that the code is not taking the ID value from the table .

when i write the Id inside the getWorkflowbyId () it works , so I am sure that the problem is in getting the value of Id from the Table .

so can you help me please?

0 Kudos
eoinbyrne
Expert
Expert

This might help

It can start an monitor a list of workflows to completion

// start the workflow given in wf with the inputs give in wfInputs

// + then store the workflowToken into the toksArray

function startWorkflow(name, wf, wfInputs, toksArray)

{

     System.log("Executing the workflow '" + wf.name + "' for ' " + name + "'");

     var wfToken = wf.execute(wfInputs);

     toksArray.push(wfToken);

}

// create the Properties map of workflow inputs

// These are defined in pairs - name and value

// Names must match the name of the input on the target workflow

// + the value type must match the expected type of the input

// You can modify this function to have as many as you need here, just follow the rules above

function createWorkflowInputs(inputName1, inputValue1)

{

     // create the properties map to hold all the inputs

     var wfInputs = new Properties();

     // add all the inputs to the map in pairs

     // NOTE: To add a third input, add the n/v pair to the parameter list above then

     // put a line underneath here to add them to the inputs map

     wfInputs.put(inputName1, inputValue1);

     return wfInputs;

}

function monitorTokensToCompletion(toksArray)

{

     System.log("Waiting for batch of " + toksArray.length + " workflows to complete....");

     // use the OOTB action to wait for the batch to finish

     // the return value here is the array of tokens

     var completed = System.getModule("com.vmware.library.vc.basic").waitForCompletionForBatchWorkflow(toksArray);

     // copy the completed tokens to the global token array

     for each(var tok in toksArray)

     {

          wfTokens.push(tok);

     }

     System.log("Batch monitoring cycle completed!");

}

// Maximum concurrent workflows

var MAX_BATCH_SIZE = maxConcurrentWorkflows;

// we'll store the global results for all workflows we run here

wfTokens= [];

// keep the batch tokens in this array for now, they'll be copied over the global results later

// + we will reset this after that copy when a batch has completed

var batchTokens = [];

if(inputStrings != null && inputStrings.length > 0)

{

     System.log("Starting workflows in batches of " + MAX_BATCH_SIZE + " for " + inputStrings.length + " inputs..");

     for each (var inputString in inputStrings)

     {

          System.log("Next name is " + inputString);

          // is there space in the current batch for a new entry?

          if(batchTokens.length >= MAX_BATCH_SIZE)

          {

               // Current batch is full so wait for all of those workflows to complete

               monitorTokensToCompletion(batchTokens);

               // reset the batchTokens list now as we will start a new batch on the next loop

               batchTokens = [];

          }

          // yes, we can add a new entry

          // create the inputs

          // NOTE: I've assumed that each VM is an input to the target workflow here just to show how that

          // you can pass any object types to the function

          // If you add new entries to the function parameter list then you need to modify this line to be sure

          // that the inputs are correct for each workflow invocation

          var workflowInputParams = createWorkflowInputs("inputValue", inputString);

          // start the workflow and put the token into the batch list

          startWorkflow(inputString, tWorkflow, workflowInputParams, batchTokens);

          System.log("The workflow has started for input " + inputString);

     }

     // we've completed the list of input VMs - check if there is a partial batch of workflows still running

     if(batchTokens.length > 0)

     {

          // wait for the last few workflows to complete

          monitorTokensToCompletion(batchTokens);

     }

}

System.log("Executed " + wfTokens.length + " total workflows...");

// Just printing vital bits here, you may want to change this to get better data

System.log("Name, Start Date, State, End Date");

for each(var wfTok in wfTokens)

{

     System.log(wfTok.name + "," + wfTok.startDate + "," + wfTok.state + "," + wfTok.endDate);

}

0 Kudos
ghaithsultaneh
Contributor
Contributor

thank you for your replay . my script is working if i write the Id inside the getWorkflowbyId() method, but i need to know how can i get specific value from sql table through script . i used : var subworkflowId = result.subWorkflow; // result : the output from Read process

                                                                                                                subworkflow : the field name in the Table which contains the Workflow id

0 Kudos
eoinbyrne
Expert
Expert

What does the subWorkflow do? And what is the value of the ID you are retrieving - If you do System.log(id) what does it print?

0 Kudos
ghaithsultaneh
Contributor
Contributor

subWorkflow is a field in a Table in DB  contains id value of workflow .

0 Kudos
eoinbyrne
Expert
Expert

And how are you retrieving that value? If you're using the SQL plugin you must be using a ResultSet or SQLActiveRecord? Can you print the value in the subWorkflow field using System.log?

0 Kudos
ghaithsultaneh
Contributor
Contributor

i am taking that value from Read process on that table and the output of this process is the Variable 'result' which i am using it as input for the scriptable task .so as you can see in the code i wrote , i defined a variable named subworkflow wich is taking from the SQL Active record the Id which is stored under the subworkflow field in that active record

0 Kudos
kaushikpal
Contributor
Contributor

Does all of your sub-workflows have same input parameter?

0 Kudos
eoinbyrne
Expert
Expert

OK, so this was your code

var subworkflowId = result.subWorkflow; // result is the output for read task and subWorkflow is the field name in the table

var workflowToExecute = System.getModule("com.vmware.library.workflow").getWorkflowById(subworkflowId);  // the id here is stored in the table in form of "1234452525"

var objWorkflowToken= workflowToExecute.execute();

The value of subworkflowId is being taken from the result Object. If that is an instance of SQLActiveRecord then the documented way to get the value of the subworkflowId field is like this

result.getProperty("subworkflowId"); // I realize the way you have it *should* work and probably does but, the API spec says this is the way to retrieve a value from an object of this type.

So, the second line uses the value provided in subworkflowId with the getWorkflowById action. You say that if you hard-code the ID, this line works but if you use the value you're getting from the result Object it does not return anything. This means that the problem is with the value of subworkflowId and there are two possibilities

1. subworkflowId is NULL

2. subworkflowId does not contain the ID of a workflow in the vRO system you are running this on

This is why I was asking you to print the value of subworkflowId using this line as soon as you have assigned a value to it from the result Object, i.e.,  run this code

var subworkflowId = result.subWorkflow; // result is the output for read task and subWorkflow is the field name in the table

System.log("subworkflowId == " + subworkflowId); // show the value in subworkflowId

var workflowToExecute = System.getModule("com.vmware.library.workflow").getWorkflowById(subworkflowId);  // the id here is stored in the table in form of "1234452525"

var objWorkflowToken= workflowToExecute.execute();

Once you've done that you'll know two more things

1. Whether or not the SQLActiveRecord retrieval is working (if the value of subworkflowId is printed as "null")

2 Whether or not the value for subworkflowId in the DB is a valid workflow ID (if subworkflowId has a value but it does not match the ID of any known workflow in the system)

I think that is as clear as I can be here. Please let us know how it goes

0 Kudos