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; } } };