## Serverless Workflow Specification - Examples ## Table of Contents - [Hello World](#Hello-World-Example) - [Greeting](#Greeting-Example) - [Event-based greeting](#Event-Based-Greeting-Example) - [Solving Math Problems (ForEach)](#Solving-Math-Problems-Example) - [Parallel Execution](#Parallel-Execution-Example) - [Applicant Request Decision (Switch + SubFlow)](#Applicant-Request-Decision-Example) - [Provision Orders (Error Handling)](#Provision-Orders-Example) - [Monitor Job for completion (Polling)](#Monitor-Job-Example) - [Send CloudEvent on Workflow Completion](#Send-CloudEvent-On-Workfow-Completion-Example) - [Monitor Patient Vital Signs](#Monitor-Patient-Vital-Signs-Example) - [Finalize College Application](#Finalize-College-Application-Example) ### Hello World Example #### Description This example uses two relay states. The "Hello" state statically injects the following JSON into its data input: ```json { "result": "Hello" } ``` which then becomes the data input of the transition "World" state. The "World" state merges its data input with it's injected JSON and uses a filter to set its data output to the value of the "result" property. Since it is an end state, it's data output becomes the workflow data output: ``` "Hello World!" ``` #### Workflow Definition
JSON | YAML |
---|---|
```json { "name": "Hello World Workflow", "description": "Static Hello World", "startsAt": "Hello", "states":[ { "name":"Hello", "type":"RELAY", "inject": { "result": "Hello" }, "transition": { "nextState": "World" } }, { "name":"World", "type":"RELAY", "inject": { "result": " World!" }, "stateDataFilter": { "dataOutputPath": "$.result" }, "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Hello World Workflow description: Static Hello World startsAt: Hello states: - name: Hello type: RELAY inject: result: Hello transition: nextState: World - name: World type: RELAY inject: result: " World!" stateDataFilter: dataOutputPath: "$.result" end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "name": "Greeting Workflow", "description": "Greet Someone", "startsAt": "Greet", "functions": [ { "name": "greetingFunction", "resource": "functionResourse" } ], "states":[ { "name":"Greet", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "refName": "greetingFunction", "parameters": { "name": "$.greet.name" } }, "actionDataFilter": { "dataResultsPath": "$.payload.greeting" } } ], "stateDataFilter": { "dataOutputPath": "$.greeting" }, "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Greeting Workflow description: Greet Someone startsAt: Greet functions: - name: greetingFunction resource: functionResourse states: - name: Greet type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: refName: greetingFunction parameters: name: "$.greet.name" actionDataFilter: dataResultsPath: "$.payload.greeting" stateDataFilter: dataOutputPath: "$.greeting" end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "name": "Event Based Greeting Workflow", "description": "Event Based Greeting", "startsAt": "Greet", "events": [ { "name": "GreetingEvent", "type": "greetingEventType", "source": "greetingEventSource" } ], "functions": [ { "name": "greetingFunction", "resource": "functionResourse" } ], "states":[ { "name":"Greet", "type":"EVENT", "eventsActions": [{ "eventRefs": ["GreetingEvent"], "eventDataFilter": { "inputPath": "$.data.greet" }, "actions":[ { "functionRef": { "refName": "greetingFunction", "parameters": { "name": "$.greet.name" } } } ] }], "stateDataFilter": { "dataOutputPath": "$.payload.greeting" }, "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Event Based Greeting Workflow description: Event Based Greeting startsAt: Greet events: - name: GreetingEvent type: greetingEventType source: greetingEventSource functions: - name: greetingFunction resource: functionResourse states: - name: Greet type: EVENT eventsActions: - eventRefs: - GreetingEvent eventDataFilter: inputPath: "$.data.greet" actions: - functionRef: refName: greetingFunction parameters: name: "$.greet.name" stateDataFilter: dataOutputPath: "$.payload.greeting" end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "name": "Solve Math Problems Workflow", "description": "Solve math problems", "startsAt": "Solve", "functions": [ { "name": "solveMathExpressionFunction", "resource": "functionResourse" } ], "states":[ { "name":"Solve", "type":"FOREACH", "inputCollection": "$.expressions", "inputParameter": "$.singleexpression", "outputCollection": "$.results", "startsAt": "GetResults", "states": [ { "name":"GetResults", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "refName": "solveMathExpressionFunction", "parameters": { "expression": "$.singleexpression" } } } ], "end": { "type": "DEFAULT" } } ], "stateDataFilter": { "dataOutputPath": "$.results" }, "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Solve Math Problems Workflow description: Solve math problems startsAt: Solve functions: - name: solveMathExpressionFunction resource: functionResourse states: - name: Solve type: FOREACH inputCollection: "$.expressions" inputParameter: "$.singleexpression" outputCollection: "$.results" startsAt: GetResults states: - name: GetResults type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: refName: solveMathExpressionFunction parameters: expression: "$.singleexpression" end: type: DEFAULT stateDataFilter: dataOutputPath: "$.results" end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "name": "Parallel Execution Workflow", "description": "Executes two branches in parallel", "startsAt": "ParallelExec", "states":[ { "name":"ParallelExec", "type":"PARALLEL", "branches": [ { "name": "Branch1", "startsAt": "ShortDelay", "states": [ { "name":"ShortDelay", "type":"DELAY", "timeDelay": "PT15S", "end": { "type": "DEFAULT" } } ], "waitForCompletion": false }, { "name": "Branch2", "startsAt": "LongDelay", "states": [ { "name":"LongDelay", "type":"DELAY", "timeDelay": "PT2M", "end": { "type": "DEFAULT" } } ], "waitForCompletion": false } ], "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Parallel Execution Workflow description: Executes two branches in parallel startsAt: ParallelExec states: - name: ParallelExec type: PARALLEL branches: - name: Branch1 startsAt: ShortDelay states: - name: ShortDelay type: DELAY timeDelay: PT15S end: type: DEFAULT waitForCompletion: false - name: Branch2 startsAt: LongDelay states: - name: LongDelay type: DELAY timeDelay: PT2M end: type: DEFAULT waitForCompletion: false end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "name": "Applicant Request Decision Workflow", "description": "Determine if applicant request is valid", "startsAt": "CheckApplication", "functions": [ { "name": "sendRejectionEmailFunction", "resource": "functionResourse" } ], "states":[ { "name":"CheckApplication", "type":"SWITCH", "choices": [ { "path": "$.applicant.age", "value": "18", "operator": "GreaterThanEquals", "transition": { "nextState": "StartApplication" } }, { "path": "$.applicant.age", "value": "18", "operator": "LessThan", "transition": { "nextState": "RejectApplication" } } ], "default": { "nextState": "RejectApplication" } }, { "name": "StartApplication", "type": "SUBFLOW", "workflowId": "startApplicationWorkflowId", "end": { "type": "DEFAULT" } }, { "name":"RejectApplication", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "refName": "sendRejectionEmailFunction", "parameters": { "applicant": "$.applicant" } } } ], "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Applicant Request Decision Workflow description: Determine if applicant request is valid startsAt: CheckApplication functions: - name: sendRejectionEmailFunction resource: functionResourse states: - name: CheckApplication type: SWITCH choices: - path: "$.applicant.age" value: '18' operator: GreaterThanEquals transition: nextState: StartApplication - path: "$.applicant.age" value: '18' operator: LessThan transition: nextState: RejectApplication default: nextState: RejectApplication - name: StartApplication type: SUBFLOW workflowId: startApplicationWorkflowId end: type: DEFAULT - name: RejectApplication type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: refName: sendRejectionEmailFunction parameters: applicant: "$.applicant" end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "name": "Provision Orders", "description": "Provision Orders and handle errors thrown", "startsAt": "ProvisionOrder", "functions": [ { "name": "provisionOrderFunction", "resource": "functionResourse" } ], "states":[ { "name":"ProvisionOrder", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "refName": "provisionOrderFunction", "parameters": { "order": "$.order" } } } ], "onError": [ { "expression": { "language": "spel", "body": "name eq 'MissingOrderIdException'" }, "transition": { "nextState": "MissingId" } }, { "expression": { "language": "spel", "body": "name eq 'MissingOrderItemException'" }, "transition": { "nextState": "MissingItem" } }, { "expression": { "language": "spel", "body": "name eq 'MissingOrderQuantityException'" }, "transition": { "nextState": "MissingQuantity" } } ], "stateDataFilter": { "dataOutputPath": "$.exception" }, "transition": { "nextState":"ApplyOrder" } }, { "name": "MissingId", "type": "SUBFLOW", "workflowId": "handleMissingIdExceptionWorkflow", "end": { "type": "DEFAULT" } }, { "name": "MissingItem", "type": "SUBFLOW", "workflowId": "handleMissingItemExceptionWorkflow", "end": { "type": "DEFAULT" } }, { "name": "MissingQuantity", "type": "SUBFLOW", "workflowId": "handleMissingQuantityExceptionWorkflow", "end": { "type": "DEFAULT" } }, { "name": "ApplyOrder", "type": "SUBFLOW", "workflowId": "applyOrderWorkflowId", "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Provision Orders description: Provision Orders and handle errors thrown startsAt: ProvisionOrder functions: - name: provisionOrderFunction resource: functionResourse states: - name: ProvisionOrder type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: refName: provisionOrderFunction parameters: order: "$.order" onError: - expression: language: spel body: name eq 'MissingOrderIdException' transition: nextState: MissingId - expression: language: spel body: name eq 'MissingOrderItemException' transition: nextState: MissingItem - expression: language: spel body: name eq 'MissingOrderQuantityException' transition: nextState: MissingQuantity stateDataFilter: dataOutputPath: "$.exception" transition: nextState: ApplyOrder - name: MissingId type: SUBFLOW workflowId: handleMissingIdExceptionWorkflow end: type: DEFAULT - name: MissingItem type: SUBFLOW workflowId: handleMissingItemExceptionWorkflow end: type: DEFAULT - name: MissingQuantity type: SUBFLOW workflowId: handleMissingQuantityExceptionWorkflow end: type: DEFAULT - name: ApplyOrder type: SUBFLOW workflowId: applyOrderWorkflowId end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "name": "Job Monitoring", "description": "Monitor finished execution of a submitted job", "startsAt": "SubmitJob", "functions": [ { "name": "submitJob", "resource": "submitJobResource" }, { "name": "checkJobStatus", "resource": "checkJobStatusResource" }, { "name": "reportJobSuceeded", "resource": "reportJobSuceededResource" }, { "name": "reportJobFailed", "resource": "reportJobFailedResource" } ], "states":[ { "name":"SubmitJob", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "refName": "submitJob", "parameters": { "name": "$.job.name" } }, "actionDataFilter": { "dataResultsPath": "$.jobuid" } } ], "onError": [ { "expression": { "language": "spel", "body": "name != null" }, "transition": { "nextState": "SubmitError" } } ], "stateDataFilter": { "dataOutputPath": "$.jobuid" }, "transition": { "nextState":"WaitForCompletion" } }, { "name": "SubmitError", "type": "SUBFLOW", "workflowId": "handleJobSubmissionErrorWorkflow", "end": { "type": "DEFAULT" } }, { "name": "WaitForCompletion", "type": "DELAY", "timeDelay": "PT5S", "transition": { "nextState":"GetJobStatus" } }, { "name":"GetJobStatus", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "refName": "checkJobStatus", "parameters": { "name": "$.jobuid" } }, "actionDataFilter": { "dataResultsPath": "$.jobstatus" } } ], "stateDataFilter": { "dataOutputPath": "$.jobstatus" }, "transition": { "nextState":"DetermineCompletion" } }, { "name":"DetermineCompletion", "type":"SWITCH", "choices": [ { "path": "$.jobstatus", "value": "SUCCEEDED", "operator": "Equals", "transition": { "nextState": "JobSucceeded" } }, { "path": "$.jobstatus", "value": "FAILED", "operator": "Equals", "transition": { "nextState": "JobFailed" } } ], "default": "WaitForCompletion" }, { "name":"JobSucceeded", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "refName": "reportJobSuceeded", "parameters": { "name": "$.jobuid" } } } ], "end": { "type": "DEFAULT" } }, { "name":"JobFailed", "type":"OPERATION", "actionMode":"SEQUENTIAL", "actions":[ { "functionRef": { "name": "reportJobFailed", "parameters": { "name": "$.jobuid" } } } ], "end": { "type": "DEFAULT" } } ] } ``` | ```yaml name: Job Monitoring description: Monitor finished execution of a submitted job startsAt: SubmitJob functions: - name: submitJob resource: submitJobResource - name: checkJobStatus resource: checkJobStatusResource - name: reportJobSuceeded resource: reportJobSuceededResource - name: reportJobFailed resource: reportJobFailedResource states: - name: SubmitJob type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: refName: submitJob parameters: name: "$.job.name" actionDataFilter: dataResultsPath: "$.jobuid" onError: - expression: language: spel body: name != null transition: nextState: SubmitError stateDataFilter: dataOutputPath: "$.jobuid" transition: nextState: WaitForCompletion - name: SubmitError type: SUBFLOW workflowId: handleJobSubmissionErrorWorkflow end: type: DEFAULT - name: WaitForCompletion type: DELAY timeDelay: PT5S transition: nextState: GetJobStatus - name: GetJobStatus type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: refName: checkJobStatus parameters: name: "$.jobuid" actionDataFilter: dataResultsPath: "$.jobstatus" stateDataFilter: dataOutputPath: "$.jobstatus" transition: nextState: DetermineCompletion - name: DetermineCompletion type: SWITCH choices: - path: "$.jobstatus" value: SUCCEEDED operator: Equals transition: nextState: JobSucceeded - path: "$.jobstatus" value: FAILED operator: Equals transition: nextState: JobFailed default: WaitForCompletion - name: JobSucceeded type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: refName: reportJobSuceeded parameters: name: "$.jobuid" end: type: DEFAULT - name: JobFailed type: OPERATION actionMode: SEQUENTIAL actions: - functionRef: name: reportJobFailed parameters: name: "$.jobuid" end: type: DEFAULT ``` |
JSON | YAML |
---|---|
```json { "id": "sendcloudeventonprovision", "name": "Send CloudEvent on provision completion", "version": "1.0", "startsAt": "ProvisionOrdersState", "events": [ { "name": "provisioningCompleteEvent", "type": "provisionCompleteType" } ], "functions": [ { "name": "provisionOrderFunction", "resource": "functionResourse" } ], "states": [ { "name": "ProvisionOrdersState", "type": "FOREACH", "inputCollection": "$.orders", "inputParameter": "$.singleorder", "outputCollection": "$.results", "startsAt": "DoProvision", "states": [ { "name": "DoProvision", "type": "OPERATION", "actions": [ { "functionRef": { "refName": "provisionOrderFunction", "parameters": { "order": "$.order" } } } ], "end": { "type": "DEFAULT" } } ], "stateDataFilter": { "dataOutputPath": "$.provisionedOrders" }, "end": { "type": "EVENT", "produceEvent": { "nameRef": "provisioningCompleteEvent", "data": "$.provisionedOrders" } } } ] } ``` | ```yaml id: sendcloudeventonprovision name: Send CloudEvent on provision completion version: '1.0' startsAt: ProvisionOrdersState events: - name: provisioningCompleteEvent type: provisionCompleteType functions: - name: provisionOrderFunction resource: functionResourse states: - name: ProvisionOrdersState type: FOREACH inputCollection: "$.orders" inputParameter: "$.singleorder" outputCollection: "$.results" startsAt: DoProvision states: - name: DoProvision type: OPERATION actions: - functionRef: refName: provisionOrderFunction parameters: order: "$.order" end: type: DEFAULT stateDataFilter: dataOutputPath: "$.provisionedOrders" end: type: EVENT produceEvent: nameRef: provisioningCompleteEvent data: "$.provisionedOrders" ``` |
JSON | YAML |
---|---|
```json { "id": "patientVitalsWorkflow", "name": "Monitor Patient Vitals", "version": "1.0", "startsAt": "MonitorVitals", "events": [ { "name": "HighBodyTemperature", "type": "org.monitor.highBodyTemp", "source": "monitoringSource", "correlationToken": "patientId" }, { "name": "HighBloodPressure", "type": "org.monitor.highBloodPressure", "source": "monitoringSource", "correlationToken": "patientId" }, { "name": "HighRespirationRate", "type": "org.monitor.highRespirationRate", "source": "monitoringSource", "correlationToken": "patientId" } ], "functions": [ { "name": "callPulmonologist", "type": "function", "resource": "callPulmonologistResource" }, { "name": "sendTylenolOrder", "type": "function", "resource": "sendTylenolOrderFunction" }, { "name": "callNurse", "type": "function", "resource": "callNurseResource" } ], "states": [ { "name": "MonitorVitals", "type": "EVENT", "exclusive": true, "eventsActions": [{ "eventRefs": ["HighBodyTemperature"], "actions": [{ "functionref": { "refname": "sendTylenolOrder", "parameters": { "patientid": "$.patientId" } } }] }, { "eventRefs": ["HighBloodPressure"], "actions": [{ "functionref": { "refname": "callNurse", "parameters": { "patientid": "$.patientId" } } }] }, { "eventRefs": ["HighRespirationRate"], "actions": [{ "functionref": { "refname": "callPulmonologist", "parameters": { "patientid": "$.patientId" } } }] } ], "end": { "type": "TERMINATE" } }] } ``` | ```yaml id: patientVitalsWorkflow name: Monitor Patient Vitals version: '1.0' startsAt: MonitorVitals events: - name: HighBodyTemperature type: org.monitor.highBodyTemp source: monitoringSource correlationToken: patientId - name: HighBloodPressure type: org.monitor.highBloodPressure source: monitoringSource correlationToken: patientId - name: HighRespirationRate type: org.monitor.highRespirationRate source: monitoringSource correlationToken: patientId functions: - name: callPulmonologist type: function resource: callPulmonologistResource - name: sendTylenolOrder type: function resource: sendTylenolOrderFunction - name: callNurse type: function resource: callNurseResource states: - name: MonitorVitals type: EVENT exclusive: true eventsActions: - eventRefs: - HighBodyTemperature actions: - functionref: refname: sendTylenolOrder parameters: patientid: "$.patientId" - eventRefs: - HighBloodPressure actions: - functionref: refname: callNurse parameters: patientid: "$.patientId" - eventRefs: - HighRespirationRate actions: - functionref: refname: callPulmonologist parameters: patientid: "$.patientId" end: type: TERMINATE ``` |
JSON | YAML |
---|---|
```json { "id": "finalizeCollegeApplication", "name": "Finalize College Application", "version": "1.0", "startsAt": "FinalizeApplication", "events": [ { "name": "ApplicationSubmitted", "type": "org.application.submitted", "source": "applicationsource", "correlationToken": "applicantId" }, { "name": "SATScoresReceived", "type": "org.application.satscores", "source": "applicationsource", "correlationToken": "applicantId" }, { "name": "RecommendationLetterReceived", "type": "org.application.recommendationLetter", "source": "applicationsource", "correlationToken": "applicantId" } ], "functions": [ { "name": "finalizeApplicationFunction", "type": "function", "resource": "finalizeApplicationResource" } ], "states": [ { "name": "FinalizeApplication", "type": "EVENT", "exclusive": false, "eventsActions": [ { "eventRefs": [ "ApplicationSubmitted", "SATScoresReceived", "RecommendationLetterReceived" ], "actions": [ { "functionref": { "refname": "finalizeApplicationFunction", "parameters": { "student": "$.applicantId" } } } ] } ], "end": { "type": "TERMINATE" } } ] } ``` | ```yaml id: finalizeCollegeApplication name: Finalize College Application version: '1.0' startsAt: FinalizeApplication events: - name: ApplicationSubmitted type: org.application.submitted source: applicationsource correlationToken: applicantId - name: SATScoresReceived type: org.application.satscores source: applicationsource correlationToken: applicantId - name: RecommendationLetterReceived type: org.application.recommendationLetter source: applicationsource correlationToken: applicantId functions: - name: finalizeApplicationFunction type: function resource: finalizeApplicationResource states: - name: FinalizeApplication type: EVENT exclusive: false eventsActions: - eventRefs: - ApplicationSubmitted - SATScoresReceived - RecommendationLetterReceived actions: - functionref: refname: finalizeApplicationFunction parameters: student: "$.applicantId" end: type: TERMINATE ``` |