Model import workflow example
Creating the workflow
Use IafWorkflowSvc.createWorkflowDef to create a Workflow in the Workflow Service.
In the addDataSources.js setup script the bimpk_import and map_revit_type workflows are created. The syntax changes to note are as follows:
- The
_nameproperty now must not contain spaces - The steps are now contained in the
_taskDefsarray. - Script execution tasks must contain the property and value,
_type: "SCRIPT_EXECUTION". - You can add
_retryCountand_timeoutproperties to tasks - Define input parameters in the Workflow's
_inputParamsobject - For a task,
_inputParamsreplaces_actualParams - Describe input params with the syntax
"${workflow.input._myParam}"
async function addDataSources(params, libraries, ctx) {
console.log("Running addDataSources...");
return new Promise(async (resolve, reject) => {
try {
const { PlatformApi } = libraries;
const bimpkWorkflowResult = await PlatformApi.IafWorkflowSvc.createWorkflowDef({
_name: "BIMPK_Import",
_description: "BIMPK Import",
_namespaces: ctx._namespaces,
_userType: "bimpk_import",
_taskDefs: [
{
_name: "default_script_target",
_type: "SCRIPT_EXECUTION",
_inputParams: {
_userType: "iaf_import_model",
_scriptName: "importModel",
_fileId: "${workflow.input._fileId}",
_fileVersionId: "${workflow.input._fileVersionId}",
},
_sequenceno: 1,
_retryCount: 0
},
],
_inputParams: {
_fileId: {
type: "string",
value: "",
encrypt: "false"
},
_fileVersionId: {
type: "string",
value: "",
encrypt: "false"
}
}
},
ctx);
console.log(
"Completed CreateBIMPKWorkflow ==== BIMPK Import Add Workflow Response",
JSON.stringify(bimpkWorkflowResult)
);
}
Running the workflow from the Manage Model page
Define the workflow request params.
let req = {
_workflowDefId: mappingWorkflow._id,
_inputParams: {
bimModel: model
},
};
let ctx = { isFormData: false };
const pollRes = await this.runPolledWorkflow(mappingWorkflow, req, ctx);
Run the Workflow using IafWorkflowSvc.runWorkflow:
async runPolledWorkflow(workflow, req, ctx) {
try {
let result = await IafWorkflowSvc.runWorkflow(
workflow._id,
req,
ctx
);
console.log("runPolledWorkflow result: ", result);
return await this.pollWorkflow(result)
} catch (e) {
console.log("Workflow error: ", e);
throw e;
}
}
Polling the workflow
Call IafWorkflowSvc.getWorkflowStatus to get the Workflow's status.
When polling the Workflow, be aware that the Workflow and Task statuses have changed.
- Check the Task statuses for
"SCHEDULED","QUEUED","IN_PROGRESS","FAIL", and"COMPLETE". - Check the Workflow itself for a
"TIMED_OUT"status.
async pollWorkflow(workflowResult, index) {
console.log('pollWorkflow workflowResult : ', workflowResult);
let attempts = 0;
const ctx = {
_namespaces: this.props.selectedItems.selectedProject._namespaces
}
while (attempts < 6000) {
try {
const workflowRunStatus = await IafWorkflowSvc.getWorkflowStatus(
workflowResult._id,
ctx
);
console.log('mapping workflowRunStatus: ', workflowRunStatus)
if (workflowRunStatus) {
//First, check if the workflow has timed out
const overallStatus = workflowRunStatus._status;
if (overallStatus === 'TIMED_OUT') {
this.setState({ workflowStepRunStatus: 'TIMED_OUT' });
throw new Error(`Workflow has timed out`);
}
//Check status of tasks in the workflow
let workflowStepRunStatus = workflowRunStatus?._tasks;
workflowStepRunStatus.forEach((task) => {
task.id = task._id; //need an id for mobiScroll.listView
});
//workflowStepRunStatus.reverse(); //show latest status at top
this.setState({
workflowRunStatus: workflowRunStatus,
workflowStepRunStatus: workflowStepRunStatus,
});
const failStatusString = ['FAIL', 'FAILED'];
const errStatus = workflowStepRunStatus.filter(run_status => failStatusString.includes(run_status._status));
const queuedStatus = workflowStepRunStatus.filter(run_status => run_status._status === "QUEUED");
const runningStatus = workflowStepRunStatus.filter(run_status => run_status._status === "IN_PROGRESS");
if (!_.isEmpty(errStatus)) {
this.setState({ workflowStepRunStatus: errStatus });
}
if (!_.isEmpty(queuedStatus)) {
this.setState({ workflowStepRunStatus: queuedStatus });
}
if (!_.isEmpty(runningStatus)) {
this.setState({ workflowStepRunStatus: runningStatus });
}
console.log(`Workflow status:`, {
errors: errStatus.length,
queued: queuedStatus.length,
running: runningStatus.length,
attempt: attempts
});
if (!_.isEmpty(errStatus)) {
throw new Error(`Workflow encountered errors: ${JSON.stringify(errStatus)}`);
}
if (_.isEmpty(queuedStatus) && _.isEmpty(runningStatus)) {
workflowStepRunStatus.forEach((step) => step._status = 'COMPLETED');
return {
workflowId: workflowResult._id,
status: 'COMPLETED',
steps: workflowStepRunStatus
};
}
const startWait = Date.now();
while (Date.now() - startWait < 10000) {
const x = Math.random();
}
} else {
console.log('No workflowRunStatus found for workflowResult: ', workflowResult);
}
attempts++;
} catch (error) {
console.error(`Error polling workflow:`, JSON.stringify(error));
throw error;
}
}
};