diff --git a/README.md b/README.md
index 8cdabce1..557822f6 100644
--- a/README.md
+++ b/README.md
@@ -4,92 +4,111 @@
[](https://serverlessworkflow.io/)
[
](https://twitter.com/CNCFWorkflow)
+## Table of Contents
+
+- [About](#about)
+- [Ecosystem](#ecosystem)
+ + [DSL](dsl.md)
+ + [CTK](/ctk/readme.md)
+ + [SDKs](#sdks)
+ + [Runtimes](#runtimes)
+ + [Tooling](#Tooling)
+ + [Landscape](#cncf-landscape)
+- [Documentation](#documentation)
+- [Community](#community)
+ + [Communication](#communication)
+ + [Governance](#governance)
+ + [Code of Conduct](#code-of-conduct)
+ + [Weekly Meetings](#weekly-meetings)
++ [Support](#support)
+ - [Adoption](#adoption)
+ - [Sponsoring](#sponsoring)
+
## About
-CNCF Serverless Workflow defines a vendor-neutral, open-source, and fully community-driven
-ecosystem for defining and running DSL-based workflows that target the Serverless technology domain.
+Serverless Workflow presents a vendor-neutral, open-source, and entirely community-driven ecosystem tailored for defining and executing DSL-based workflows in the realm of Serverless technology.
-This project is composed of:
+The Serverless Workflow DSL is a high-level language that reshapes the terrain of workflow creation, boasting a design that is ubiquitous, intuitive, imperative, and fluent.
-* [Specification](specification.md) for defining DSL-based workflows
-* [Developer SDKs](#sdks) for different programming languages
-* [Workflow runtimes](#runtimes) supporting the specification
-* Developer [tooling support](#tooling) for writing DSL-based workflows
+Bid farewell to convoluted coding and platform dependencies—now, crafting powerful workflows is effortlessly within reach for everyone!
-CNCF Serverless Workflow is hosted by the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io/) and was approved as a
-Cloud Native Sandbox level project on July 14, 2020.
+Key features:
-## Table of Contents
+- **Easy to Use**: Designed for universal understanding, Serverless Workflow DSL enables users to quickly grasp workflow concepts and create complex workflows effortlessly.
+- **Event Driven**: Seamlessly integrate events into workflows with support for various formats, including CloudEvents, allowing for event-driven workflow architectures.
+- **Service Oriented**: The Serverless Workflow DSL empowers developers to seamlessly integrate with service-oriented architectures, allowing them to define workflows that interact with various services over standard application protocols like HTTP, GRPC, OpenAPI, AxsyncAPI, and more.
+- **FaaS Centric**: Seamlessly invoke functions hosted on various platforms within workflows, promoting a function-as-a-service (FaaS) paradigm and enabling microservices architectures.
+- **Timely**: Define timeouts for workflows and tasks to manage execution duration effectively.
+- **Fault Tolerant**: Easily define error handling strategies to manage and recover from errors that may occur during workflow execution, ensuring robustness and reliability.
+- **Schedulable**: Schedule workflows using CRON expressions or trigger them based on events, providing control over workflow execution timing.
+- **Interoperable**: Integrates seamlessly with different services and resources.
+- **Robust**: Offers features such as conditional branching, event handling, and looping constructs.
+- **Scalable**: Promotes code reusability, maintainability, and scalability across different environments.
-- [CNCF Landscape](#CNCF-Landscape)
-- [Releases](#Releases)
-- [Runtimes](#Runtimes)
-- [SDKs](#SDKs)
-- [Tooling](#Tooling)
-- [Community](#Community)
- - [Communication](#Communication)
- - [Code of Conduct](#Code-of-Conduct)
- - [Weekly Meetings](#Weekly-Meetings)
-- [Repository Structure](#Repository-Structure)
-- [Support](#Support)
+## Ecosystem
-## CNCF Landscape
+Serverless Workflow ecosystem is hosted by the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io/) and was approved as a
+Cloud Native Sandbox level project on July 14, 2020.
-Serverless Workflow project falls under the [CNCF "App Definition and Development"](https://landscape.cncf.io/card-mode?category=app-definition-and-development&grouping=category) category.
+It encompasses a comprehensive suite of components and tools designed to facilitate the creation, management, and execution of serverless workflows.
-It is a member project of the [CNCF Serverless Working Group](https://github.com/cncf/wg-serverless).
+1. **[DSL](dsl.md) (Domain Specific Language)**: The core of the ecosystem, defining the fundamental syntax and semantics of Serverless Workflow specifications.
-
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: hello-world-parameters- -spec: - entrypoint: whalesay - arguments: - parameters: - - name: message - value: hello world - - templates: - - name: whalesay - inputs: - parameters: - - name: message - container: - image: docker/whalesay - command: [cowsay] - args: ["{{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: hello-world-parameters -name: Hello World with parameters -version: '1.0.0' -specVersion: '0.8' -start: whalesay -functions: -- name: whalesayimage - metadata: - image: docker/whalesay - command: cowsay -states: -- name: whalesay - type: operation - actions: - - functionRef: - refName: whalesayimage - arguments: - message: "${ .message }" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: steps- -spec: - entrypoint: hello-hello-hello - templates: - - name: hello-hello-hello - steps: - - - name: hello1 # hello1 is run before the following steps - template: whalesay - arguments: - parameters: - - name: message - value: "hello1" - - - name: hello2a # double dash => run after previous step - template: whalesay - arguments: - parameters: - - name: message - value: "hello2a" - - name: hello2b # single dash => run in parallel with previous step - template: whalesay - arguments: - parameters: - - name: message - value: "hello2b" - - name: whalesay - inputs: - parameters: - - name: message - container: - image: docker/whalesay - command: [cowsay] - args: ["{{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: hello-hello-hello -name: Multi Step Hello -version: '1.0.0' -specVersion: '0.8' -start: hello1 -functions: -- name: whalesayimage - metadata: - image: docker/whalesay - command: cowsay -states: -- name: hello1 - type: operation - actions: - - functionRef: - refName: whalesayimage - arguments: - message: hello1 - transition: parallelhello -- name: parallelhello - type: parallel - completionType: allOf - branches: - - name: hello2a-branch - actions: - - functionRef: - refName: whalesayimage - arguments: - message: hello2a - - name: hello2b-branch - actions: - - functionRef: - refName: whalesayimage - arguments: - message: hello2b - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: dag-diamond- -spec: - entrypoint: diamond - templates: - - name: echo - inputs: - parameters: - - name: message - container: - image: alpine:3.7 - command: [echo, "{{inputs.parameters.message}}"] - - name: diamond - dag: - tasks: - - name: A - template: echo - arguments: - parameters: [{name: message, value: A}] - - name: B - dependencies: [A] - template: echo - arguments: - parameters: [{name: message, value: B}] - - name: C - dependencies: [A] - template: echo - arguments: - parameters: [{name: message, value: C}] - - name: D - dependencies: [B, C] - template: echo - arguments: - parameters: [{name: message, value: D}] -``` - - | -- -```yaml -id: dag-diamond- -name: DAG Diamond Example -version: '1.0.0' -specVersion: '0.8' -start: A -functions: -- name: echo - metadata: - image: alpine:3.7 - command: '[echo, "{{inputs.parameters.message}}"]' -states: -- name: A - type: operation - actions: - - functionRef: - refName: echo - arguments: - message: A - transition: parallelecho -- name: parallelecho - type: parallel - completionType: allOf - branches: - - name: B-branch - actions: - - functionRef: - refName: echo - arguments: - message: B - - name: C-branch - actions: - - functionRef: - refName: echo - arguments: - message: C - transition: D -- name: D - type: operation - actions: - - functionRef: - refName: echo - arguments: - message: D - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: scripts-bash- -spec: - entrypoint: bash-script-example - templates: - - name: bash-script-example - steps: - - - name: generate - template: gen-random-int-bash - - - name: print - template: print-message - arguments: - parameters: - - name: message - value: "{{steps.generate.outputs.result}}" # The result of the here-script - - - name: gen-random-int-bash - script: - image: debian:9.4 - command: [bash] - source: | # Contents of the here-script - cat /dev/urandom | od -N2 -An -i | awk -v f=1 -v r=100 '{printf "%i\n", f + r * $1 / 65536}' - - - name: gen-random-int-python - script: - image: python:alpine3.6 - command: [python] - source: | - import random - i = random.randint(1, 100) - print(i) - - - name: gen-random-int-javascript - script: - image: node:9.1-alpine - command: [node] - source: | - var rand = Math.floor(Math.random() * 100); - console.log(rand); - - - name: print-message - inputs: - parameters: - - name: message - container: - image: alpine:latest - command: [sh, -c] - args: ["echo result was: {{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: scripts-bash- -name: Scripts and Results Example -version: '1.0.0' -specVersion: '0.8' -start: generate -functions: -- name: gen-random-int-bash - metadata: - image: debian:9.4 - command: bash - source: |- - cat /dev/urandom | od -N2 -An -i | awk -v f=1 -v r=100 '{printf "%i - ", f + r * $1 / 65536}' -- name: gen-random-int-python - metadata: - image: python:alpine3.6 - command: python - source: "import random \ni = random.randint(1, 100) \nprint(i)\n" -- name: gen-random-int-javascript - metadata: - image: node:9.1-alpine - command: node - source: "var rand = Math.floor(Math.random() * 100); \nconsole.log(rand);\n" -- name: printmessagefunc - metadata: - image: alpine:latest - command: sh, -c - source: 'echo result was: ${ .inputs.parameters.message }' -states: -- name: generate - type: operation - actions: - - functionRef: gen-random-int-bash - actionDataFilter: - results: "${ .results }" - transition: print-message -- name: print-message - type: operation - actions: - - functionRef: - refName: printmessagefunc - arguments: - message: "${ .results }" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: loops- -spec: - entrypoint: loop-example - templates: - - name: loop-example - steps: - - - name: print-message - template: whalesay - arguments: - parameters: - - name: message - value: "{{item}}" - withItems: # invoke whalesay once for each item in parallel - - hello world # item 1 - - goodbye world # item 2 - - - name: whalesay - inputs: - parameters: - - name: message - container: - image: docker/whalesay:latest - command: [cowsay] - args: ["{{inputs.parameters.message}}"] -``` - - | -- -```yaml -id: loops- -name: Loop over data example -version: '1.0.0' -specVersion: '0.8' -start: injectdata -functions: -- name: whalesay - metadata: - image: docker/whalesay:latest - command: cowsay -states: -- name: injectdata - type: inject - data: - greetings: - - hello world - - goodbye world - transition: printgreetings -- name: printgreetings - type: foreach - inputCollection: "${ .greetings }" - iterationParam: greeting - actions: - - name: print-message - functionRef: - refName: whalesay - arguments: - message: "${ .greeting }" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: coinflip- -spec: - entrypoint: coinflip - templates: - - name: coinflip - steps: - # flip a coin - - - name: flip-coin - template: flip-coin - # evaluate the result in parallel - - - name: heads - template: heads # call heads template if "heads" - when: "{{steps.flip-coin.outputs.result}} == heads" - - name: tails - template: tails # call tails template if "tails" - when: "{{steps.flip-coin.outputs.result}} == tails" - - # Return heads or tails based on a random number - - name: flip-coin - script: - image: python:alpine3.6 - command: [python] - source: | - import random - result = "heads" if random.randint(0,1) == 0 else "tails" - print(result) - - - name: heads - container: - image: alpine:3.6 - command: [sh, -c] - args: ["echo \"it was heads\""] - - - name: tails - container: - image: alpine:3.6 - command: [sh, -c] - args: ["echo \"it was tails\""] -``` - - | -- -```yaml -id: coinflip- -name: Conditionals Example -version: '1.0.0' -specVersion: '0.8' -start: flip-coin -functions: -- name: flip-coin-function - metadata: - image: python:alpine3.6 - command: python - source: import random result = "heads" if random.randint(0,1) == 0 else "tails" - print(result) -- name: echo - metadata: - image: alpine:3.6 - command: sh, -c -states: -- name: flip-coin - type: operation - actions: - - functionRef: flip-coin-function - actionDataFilter: - results: "${ .flip.result }" - transition: show-flip-results -- name: show-flip-results - type: switch - dataConditions: - - condition: "${ .flip | .result == \"heads\" }" - transition: show-results-heads - - condition: "${ .flip | .result == \"tails\" }" - transition: show-results-tails -- name: show-results-heads - type: operation - actions: - - functionRef: echo - actionDataFilter: - results: it was heads - end: true -- name: show-results-tails - type: operation - actions: - - functionRef: echo - actionDataFilter: - results: it was tails - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: retry-backoff- -spec: - entrypoint: retry-backoff - templates: - - name: retry-backoff - retryStrategy: - limit: 10 - retryPolicy: "Always" - backoff: - duration: "1" # Must be a string. Default unit is seconds. Could also be a Duration, e.g.: "2m", "6h", "1d" - factor: 2 - maxDuration: "1m" # Must be a string. Default unit is seconds. Could also be a Duration, e.g.: "2m", "6h", "1d" - affinity: - nodeAntiAffinity: {} - container: - image: python:alpine3.6 - command: ["python", -c] - # fail with a 66% probability - args: ["import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code)"] -``` - - | -- -```yaml -id: retry-backoff- -name: Retry Example -version: '1.0.0' -specVersion: '0.8' -start: retry-backoff -functions: -- name: fail-function - metadata: - image: python:alpine3.6 - command: python -retries: -- name: All workflow errors retry strategy - maxAttempts: 10 - delay: PT1S - maxDelay: PT1M - multiplier: 2 -states: -- name: retry-backoff - type: operation - actions: - - functionRef: - refName: flip-coin-function - arguments: - args: - - import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code) - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: coinflip-recursive- -spec: - entrypoint: coinflip - templates: - - name: coinflip - steps: - # flip a coin - - - name: flip-coin - template: flip-coin - # evaluate the result in parallel - - - name: heads - template: heads # call heads template if "heads" - when: "{{steps.flip-coin.outputs.result}} == heads" - - name: tails # keep flipping coins if "tails" - template: coinflip - when: "{{steps.flip-coin.outputs.result}} == tails" - - - name: flip-coin - script: - image: python:alpine3.6 - command: [python] - source: | - import random - result = "heads" if random.randint(0,1) == 0 else "tails" - print(result) - - - name: heads - container: - image: alpine:3.6 - command: [sh, -c] - args: ["echo \"it was heads\""] -``` - - | -- -```yaml -id: coinflip-recursive- -name: Recursion Example -version: '1.0.0' -specVersion: '0.8' -start: flip-coin-state -functions: -- name: heads-function - metadata: - image: alpine:3.6 - command: echo "it was heads" -- name: flip-coin-function - metadata: - image: python:alpine3.6 - command: python - source: import random result = "heads" if random.randint(0,1) == 0 else "tail" print(result) -states: -- name: flip-coin-state - type: operation - actions: - - functionRef: flip-coin-function - actionDataFilter: - results: "${ .steps.flip-coin.outputs.result }" - transition: flip-coin-check -- name: flip-coin-check - type: switch - dataConditions: - - condition: "${ .steps.flip-coin.outputs | .result == \"tails\" }" - transition: flip-coin-state - - condition: "${ .steps.flip-coin.outputs | .result == \"heads\" }" - transition: heads-state -- name: heads-state - type: operation - actions: - - functionRef: - refName: heads-function - arguments: - args: echo "it was heads" - end: true -``` - - | -
Argo | -Serverless Workflow | -
---|---|
- -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: exit-handlers- -spec: - entrypoint: intentional-fail - onExit: exit-handler # invoke exit-handler template at end of the workflow - templates: - # primary workflow template - - name: intentional-fail - container: - image: alpine:latest - command: [sh, -c] - args: ["echo intentional failure; exit 1"] - - name: exit-handler - steps: - - - name: notify - template: send-email - - name: celebrate - template: celebrate - when: "{{workflow.status}} == Succeeded" - - name: cry - template: cry - when: "{{workflow.status}} != Succeeded" - - name: send-email - container: - image: alpine:latest - command: [sh, -c] - args: ["echo send e-mail: {{workflow.name}} {{workflow.status}}"] - - name: celebrate - container: - image: alpine:latest - command: [sh, -c] - args: ["echo hooray!"] - - name: cry - container: - image: alpine:latest - command: [sh, -c] - args: ["echo boohoo!"] -``` - - | -- -```yaml -id: exit-handlers- -name: Exit/Error Handling Example -version: '1.0.0' -specVersion: '0.8' -autoRetries: true -start: intentional-fail-state -functions: - - name: intentional-fail-function - metadata: - image: alpine:latest - command: "[sh, -c]" - - name: send-email-function - metadata: - image: alpine:latest - command: "[sh, -c]" - - name: celebrate-cry-function - metadata: - image: alpine:latest - command: "[sh, -c]" -errors: - - name: IntentionalError - code: '404' -states: - - name: intentional-fail-state - type: operation - actions: - - functionRef: - refName: intentional-fail-function - arguments: - args: echo intentional failure; exit 1 - nonRetryableErrors: - - IntentionalError - onErrors: - - errorRef: IntentionalError - transition: send-email-state - end: true - - name: send-email-state - type: operation - actions: - - functionRef: - refName: send-email-function - arguments: - args: 'echo send e-mail: ${ .workflow.name } ${ .workflow.status }' - transition: emo-state - - name: emo-state - type: switch - dataConditions: - - condition: ${ .workflow| .status == "Succeeded" } - transition: celebrate-state - - condition: ${ .workflow| .status != "Succeeded" } - transition: cry-state - - name: celebrate-state - type: operation - actions: - - functionRef: - refName: celebrate-cry-function - arguments: - args: echo hooray! - end: true - - name: cry-state - type: operation - actions: - - functionRef: - refName: celebrate-cry-function - arguments: - args: echo boohoo! - end: true -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: processfile -name: Process File Workflow -version: '1.0.0' -specVersion: '0.8' -start: Process File -states: -- name: Process File - type: operation - actions: - - functionRef: processFile - end: true -functions: -- name: processFile - operation: file://myservice.json#process -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: processapplication -name: Process Application -version: '1.0.0' -specVersion: '0.8' -start: ProcessNewApplication -states: -- name: ProcessNewApplication - type: event - onEvents: - - eventRefs: - - ApplicationReceivedEvent - actions: - - functionRef: processApplicationFunction - - functionRef: acceptApplicantFunction - - functionRef: depositFeesFunction - end: - produceEvents: - - eventRef: NotifyApplicantEvent -functions: -- name: processApplicationFunction - operation: file://myservice.json#process -- name: acceptApplicantFunction - operation: file://myservice.json#accept -- name: depositFeesFunction - operation: file://myservice.json#deposit -events: -- name: ApplicationReceivedEvent - type: application - source: "/applications/new" -- name: NotifyApplicantEvent - type: notifications - source: "/applicants/notify" -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: simplecompensation -name: Simple Compensation -version: '1.0.0' -specVersion: '0.8' -start: Step 1 -states: -- name: Step 1 - type: operation - actions: - - functionRef: step1function - compensatedBy: Cancel Step 1 - transition: Step 2 -- name: Step 2 - type: operation - actions: - - functionRef: step2function - transition: OK? -- name: OK? - type: switch - dataConditions: - - name: 'yes' - condition: ${ .outcome | .ok == "yes" } - end: true - - name: 'no' - condition: ${ .outcome | .ok == "no" } - end: - compensate: true -- name: Cancel Step 1 - type: operation - usedForCompensation: true - actions: - - functionRef: undostep1 -functions: -- name: step1function - operation: file://myservice.json#step1 -- name: step2function - operation: file://myservice.json#step2 -- name: undostep1function - operation: file://myservice.json#undostep1 -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml ---- -id: errorwithretries -name: Error Handling With Retries Workflow -version: '1.0.0' -specVersion: '0.8' -start: Make Coffee -states: - - name: Make Coffee - type: operation - actions: - - functionRef: makeCoffee - transition: Add Milk - - name: Add Milk - type: operation - actions: - - functionRef: addMilk - retryRef: noMilkRetries - retryableErrors: - - D'oh! No more Milk! - onErrors: - - errorRef: D'oh! No more Milk! - end: true - transition: Drink Coffee - - name: Drink Coffee - type: operation - actions: - - functionRef: drinkCoffee - end: true -retries: - - name: noMilkRetries - delay: PT1M - maxAttempts: 10 -errors: - - name: D'oh! No more Milk! - code: '123' -functions: - - name: makeCoffee - operation: file://myservice.json#make - - name: addMilk - operation: file://myservice.json#add - - name: drinkCoffee - operation: file://myservice.json#drink - -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: executiontimeout -name: Execution Timeout Workflow -version: '1.0.0' -specVersion: '0.8' -start: Purchase Parts -timeouts: - workflowExecTimeout: - duration: PT7D - interrupt: true - runBefore: Handle timeout -states: -- name: Purchase Parts - type: operation - actions: - - functionRef: purchasePartsFunction - transition: Unpack Parts -- name: Unpack Parts - type: operation - actions: - - functionRef: unpackPartsFunction - end: true -- name: Handle timeout - type: operation - actions: - - functionRef: handleTimeoutFunction -functions: -- name: purchasePartsFunction - operation: file://myservice.json#purchase -- name: unpackPartsFunction - operation: file://myservice.json#unpack -- name: handleTimeoutFunction - operation: file://myservice.json#handle -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: foreachWorkflow -name: ForEach State Workflow -version: '1.0.0' -specVersion: '0.8' -start: ForEachItem -states: -- name: ForEachItem - type: foreach - inputCollection: "${ .inputsArray }" - iterationParam: "${ .inputItem }" - outputCollection: "${ .outputsArray }" - actions: - - subFlowRef: doSomethingAndWaitForMessage - end: true -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: subflowloop -name: SubFlow Loop Workflow -version: '1.0.0' -specVersion: '0.8' -start: SubflowRepeat -states: -- name: SubflowRepeat - type: operation - actions: - - functionRef: checkAndReplyToEmail - actionDataFilter: - fromStateData: ${ .someInput } - toStateData: ${ .someInput } - stateDataFilter: - output: ${ .maxChecks -= 1 } - transition: CheckCount -- name: CheckCount - type: switch - dataConditions: - - condition: ${ .maxChecks > 0 } - transition: SubflowRepeat - defaultCondition: - end: true -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: approvereport -name: Approve Report Workflow -version: '1.0.0' -specVersion: '0.8' -start: Approve Report -states: -- name: Approve Report - type: callback - action: - functionRef: managerDecideOnReport - eventRef: ReportDecisionMadeEvent - transition: Evaluate Report Decision -- name: Evaluate Report Decision - type: switch - dataConditions: - - name: Approve - condition: "${ .decision | .approved == true }" - end: true - - name: Reject - condition: "${ .decision | .approved != true }" - transition: Update Report -- name: Update Report - type: callback - action: - functionRef: workerUpdateReport - eventRef: ReportUpdatedEvent - transition: Approve Report -events: -- name: ReportDecisionMadeEvent - type: report.decisions - source: reports/decision -- name: ReportUpdatedEvent - type: report.updated - source: reports/updated -functions: -- name: managerDecideOnReport - operation: file://myservice.json#managerapproval -- name: workerUpdateReport - operation: file://myservice.json#workerupdate -``` - - | -
BPMN2 Diagram | -Serverless Workflow | -
---|---|
-
- |
-- -```yaml -id: eventdecision -name: Event Decision workflow -version: '1.0.0' -specVersion: '0.8' -start: A -states: -- name: A - type: operation - actions: - - subFlowRef: asubflowid - transition: Event Decision -- name: Event Decision - type: switch - eventConditions: - - eventRef: EventB - transition: B - - eventRef: EventC - transition: C -- name: B - type: operation - actions: - - name: doSomething - functionRef: doSomethingFunction - end: true -- name: C - type: operation - actions: - - name: doSomething - functionRef: doSomethingFunction - end: true -events: -- name: EventB - type: my.events.b - source: "/events/+" -- name: EventC - type: my.events.c - source: "/events/+" -functions: -- name: doSomethingFunction - operation: file://myservice.json#dosomething -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job } = require("brigadier"); - -events.on("exec", exec); - -function exec(e, p) { - let j1 = new Job("j1", "alpine:3.7", ["echo hello"]); - let j2 = new Job("j2", "alpine:3.7", ["echo goodbye"]); - - j1.run() - .then(() => { - return j2.run() - }) - .then(() => { - console.log("done"); - }); -}; -``` - - | -- -```yaml -id: greeting -name: Greeting Workflow -version: '1.0.0' -specVersion: '0.8' -start: GreetingState -events: -- name: execEvent - type: exec -functions: -- name: greetingFunction - metadata: - image: alpine:3.7 - command: echo -- name: consoleLogFunction - type: console -states: -- name: GreetingState - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: sayHelloAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - - name: sayGoodbyeAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - - name: logDoneAction - functionRef: - refName: consoleLogFunction - arguments: - log: done - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job } = require("brigadier"); - -events.on("exec", exec); - -async function exec(e, p) { - let j1 = new Job("j1", "alpine:3.7", ["echo hello"]); - // This will fail - let j2 = new Job("j2", "alpine:3.7", ["exit 1"]); - - try { - await j1.run(); - await j2.run(); - console.log("done"); - } catch (e) { - console.log(`Caught Exception ${e}`); - } -}; -``` - - | -- -```yaml -id: greetingwitherrorcheck -name: Greeting Workflow With Error Check -version: '1.0.0' -specVersion: '0.8' -autoRetries: true -start: GreetingState -events: -- name: execEvent - type: exec -errors: -- name: CommonError - code: '123' -functions: -- name: greetingFunction - metadata: - image: alpine:3.7 - command: echo -- name: consoleLogFunction - metadata: - type: console -states: -- name: GreetingState - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: sayHelloAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - nonRetryableErrors: - - CommonError - - name: sayGoodbyeAction - functionRef: - refName: greetingFunction - arguments: - greeting: hello - nonRetryableErrors: - - CommonError - - name: logDoneAction - functionRef: - refName: consoleLogFunction - arguments: - log: done - nonRetryableErrors: - - CommonError - onErrors: - - errorRef: CommonError - transition: HandleErrorState - end: true -- name: HandleErrorState - type: operation - actions: - - name: logErrorAction - functionRef: - refName: consoleLogFunction - arguments: - log: Caught Exception ${ .exception } - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events } = require("brigadier") - -events.on("exec", () => { - console.log("==> handling an 'exec' event") -}) - -events.on("push", () => { - console.log(" **** I'm a GitHub 'push' handler") -}) -``` - - | -- -```yaml -id: multieventworkflow -name: Multiple Events Workflow -version: '1.0.0' -specVersion: '0.8' -start: GreetingState -events: -- name: execEvent - type: exec -- name: pushEvent - type: push -functions: -- name: consoleLogFunction - type: console -states: -- name: GreetingState - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: logExecEventAction - functionRef: - refName: consoleLogFunction - arguments: - log: "==> handling an 'exec' event" - - eventRefs: - - pushEvent - actions: - - name: logPushEventAction - functionRef: - refName: consoleLogFunction - arguments: - log: "**** I'm a GitHub 'push' handler" - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job, Group } = require("brigadier") - -events.on("exec", () => { - var hello = new Job("hello", "alpine:3.4", ["echo hello"]) - var goodbye = new Job("goodbye", "alpine:3.4", ["echo goodbye"]) - - var helloAgain = new Job("hello-again", "alpine:3.4", ["echo hello again"]) - var goodbyeAgain = new Job("bye-again", "alpine:3.4", ["echo bye again"]) - - - var first = new Group() - first.add(hello) - first.add(goodbye) - - var second = new Group() - second.add(helloAgain) - second.add(goodbyeAgain) - - first.runAll().then( () => second.runAll() ) -}) -``` - - | -- -```yaml -id: groupActionsWorkflow -name: Group Actions Workflow -version: '1.0.0' -specVersion: '0.8' -start: FirstGreetGroup -events: -- name: execEvent - type: exec -functions: -- name: echoFunction - metadata: - image: alpine:3.7 - command: echo -states: -- name: FirstGreetGroup - type: event - onEvents: - - eventRefs: - - execEvent - actions: - - name: firstHelloAction - functionRef: - refName: echoFunction - arguments: - message: hello - - name: firstGoodbyeAction - functionRef: - refName: echoFunction - arguments: - message: goodbye - transition: SecondGreetGroup -- name: SecondGreetGroup - type: operation - actions: - - name: secondHelloAction - functionRef: - refName: echoFunction - arguments: - message: hello-again - - name: secondGoodbyeAction - functionRef: - refName: echoFunction - arguments: - message: bye-again - end: true -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events } = require("brigadier") - -events.on("exec", (e, p) => { - console.log(">>> event " + e.type + " caused by " + e.provider) - console.log(">>> project " + p.name + " clones the repo at " + p.repo.cloneURL) -}) -``` - - | -- -```yaml -id: eventDataWorkflow -name: Event Data Workflow -version: '1.0.0' -specVersion: '0.8' -start: LogEventData -events: -- name: execEvent - type: exec - dataOnly: false -functions: -- name: consoleFunction - type: console -states: -- name: LogEventData - type: event - onEvents: - - eventRefs: - - execEvent - eventDataFilter: - toStateData: "${ .event }" - actions: - - name: eventInfoAction - functionRef: - refName: consoleFunction - arguments: - log: ">>> event ${ .event.type } caused by ${ .event.data.provider }" - - name: projectInfoAction - functionRef: - refName: consoleFunction - arguments: - log: ">>> project ${ .event.data.project.name } clones the repo at by ${ .event.data.repo.cloneURL }" - end: true - -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const { events, Job, Group } = require("brigadier") - -events.on("exec", (e, p) => { - var dest = "/mnt/brigade/share/hello.txt" - var one = new Job("one", "alpine:3.4", ["echo hello > " + dest]) - var two = new Job("two", "alpine:3.4", ["echo world >> " + dest]) - var three = new Job("three", "alpine:3.4", ["cat " + dest]) - - one.storage.enabled = true - two.storage.enabled = true - three.storage.enabled = true - - Group.runEach([one, two, three]) -}) -``` - - | -- -```yaml -id: actionResultsWorkflow -name: Action Results Workflow -version: '1.0.0' -specVersion: '0.8' -start: ExecActionsAndStoreResults -events: -- name: execEvent - type: exec -functions: -- name: greetingFunction - metadata: - image: alpine:3.7 - command: echo -- name: storeToFileFunction - metadata: - image: alpine:3.7 - command: filestore -states: -- name: ExecActionsAndStoreResults - type: event - onEvents: - - eventRefs: - - execEvent - eventDataFilter: - toStateData: "${ .event }" - actions: - - name: helloAction - actionDataFilter: - results: "${ .helloResult }" - functionRef: - refName: greetingFunction - arguments: - message: hello - - name: worldAction - actionDataFilter: - results: "${ .worldResults }" - functionRef: - refName: greetingAction - arguments: - message: world - - name: storeToFileAction - functionRef: - refName: storeToFileFunction - arguments: - destination: "${ .event.destination }" - value: "${ .helloResult } ${ .worldResults }" - end: true - -``` - - | -
Brigade | -Serverless Workflow | -
---|---|
- -```javascript -const {events} = require("brigadier") - -events.on("exec", function(e, project) { - const e2 = { - type: "next", - provider: "exec-handler", - buildID: e.buildID, - workerID: e.workerID, - cause: {event: e} - } - events.fire(e2, project) -}) - -events.on("next", (e) => { - console.log(`fired ${e.type} caused by ${e.cause.event.type}`) -}) -``` - - | -- -```yaml -id: eventDataWorkflow -name: Event Data Workflow -version: '1.0.0' -specVersion: '0.8' -start: ExecEventState -events: -- name: execEvent - type: exec - dataOnly: false -- name: nextEvent - type: next - kind: produced -functions: -- name: consoleLogFunction - type: console -states: -- name: ExecEventState - type: event - onEvents: - - eventRefs: - - execEvent - actions: [] - eventDataFilter: - toStateData: "${ .execEvent }" - transition: - nextState: NextEventState - produceEvents: - - eventRef: nextEvent - data: - type: next - provider: exec-handler - buildID: "${ .execEvent.data.buildID }" - workerID: "${ .execEvent.data.workerID }" - cause: - event: "${ .execEvent }" -- name: NextEventState - type: event - onEvents: - - eventRefs: - - nextEvent - eventDataFilter: - toStateData: "${ .nextEvent }" - actions: - - name: consoleLogAction - functionRef: - refName: consoleLogFunction - arguments: - log: "fired ${ .nextEvent.data.type } caused by ${ .nextEvent.data.cause.event }" - end: true -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -{ - "main": { - "params": [ - "args" - ], - "steps": [ - { - "step1": { - "assign": [ - { - "outputVar": "${\"Hello \" + args.firstName + \" \" + args.lastName}" - } - ] - } - }, - { - "step2": { - "return": "${outputVar}" - } - } - ] - } -} -``` - - | -- -```json -{ - "id": "greetingwithargs", - "name": "Greeting With Args", - "specVersion": "0.8", - "start": "Set Output", - "states": [ - { - "name": "Set Output", - "type": "inject", - "data": { - "outputVar": "Hello ${ .firstname + \" \" + .lastname }" - }, - "stateDataFilter": { - "output": "${ .outputVar }" - }, - "end": true - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "define": { - "assign": [ - { - "array": [ - "foo", - "ba", - "r" - ] - }, - { - "result": "" - }, - { - "i": 0 - } - ] - } - }, - { - "check_condition": { - "switch": [ - { - "condition": "${len(array) > i}", - "next": "iterate" - } - ], - "next": "exit_loop" - } - }, - { - "iterate": { - "assign": [ - { - "result": "${result + array[i]}" - }, - { - "i": "${i+1}" - } - ], - "next": "check_condition" - } - }, - { - "exit_loop": { - "return": { - "concat_result": "${result}" - } - } - } -] -``` - - | -- -```json -{ - "id": "concatarray", - "name": "Concatenating array values", - "start": "DoConcat", - "specVersion": "0.8", - "states": [ - { - "name": "DoConcat", - "type": "inject", - "data": { - "array": [ - "foo", - "ba", - "r" - ] - }, - "stateDataFilter": { - "output": "${ .array | join(\"\") }" - }, - "end": true - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "initialize": { - "assign": [ - { - "project": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_NUMBER\")}" - }, - { - "zone": "us-central1-a" - }, - { - "vmToStop": "examplevm" - } - ] - } - }, - { - "stopInstance": { - "call": "http.post", - "args": { - "url": "${\"https://compute.googleapis.com/compute/v1/projects/\"+project+\"/zones/\"+zone+\"/instances/\"+vmToStop+\"/stop\"}", - "auth": { - "type": "OAuth2" - } - }, - "result": "stopResult" - } - } -] -``` - - | -- -```json -{ - "id": "stopcomputeengine", - "name": "Stop Compute Engine", - "specVersion": "0.8", - "start": "DoStop", - "states": [ - { - "name": "DoStop", - "type": "operation", - "actions": [ - { - "functionRef": { - "refName": "StopComputeEngine", - "arguments": { - "project": "${ .project }", - "zone": "${ .zone }", - "vmToStop": "${ .vmToStop }" - } - } - } - ], - "end": true - } - ], - "functions": [ - { - "name": "StopComputeEngine", - "operation": "computeengineopenapi.json#stopengine" - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "initVariables": { - "assign": [ - { - "project": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_ID\")}" - }, - { - "topic": "mytopic1" - }, - { - "message": "Hello world!" - } - ] - } - }, - { - "publish": { - "try": { - "call": "googleapis.pubsub.v1.projects.topics.publish", - "args": { - "topic": "${\"projects/\" + project + \"/topics/\" + topic}", - "body": { - "messages": [ - { - "data": "${base64.encode(text.encode(message))}" - } - ] - } - }, - "result": "publishResult" - }, - "except": { - "as": "e", - "steps": [ - { - "handlePubSubError": { - "switch": [ - { - "condition": "${e.code == 404}", - "raise": "PubSub Topic not found" - }, - { - "condition": "${e.code == 403}", - "raise": "Error authenticating to PubSub" - } - ] - } - }, - { - "unhandledException": { - "raise": "${e}" - } - } - ] - } - } - }, - { - "last": { - "return": "${publishResult}" - } - } -] -``` - - | -- -```json -{ - "id": "publishtotopicwitherrorhandling", - "name": "Publish To Topic With Error Handling", - "specVersion": "0.8", - "start": "DoPublish", - "errors": [ - { - "name": "PubSub Topic not found", - "code": "404" - }, - { - "name": "Error authenticating to PubSub", - "code": "403" - } - ], - "states": [ - { - "name": "DoPublish", - "type": "operation", - "actions": [ - { - "functionRef": { - "refName": "PublishToTopic", - "arguments": { - "project": "${ .project }", - "topic": "${ .topic }", - "message": "${ .message }" - } - } - } - ], - "onErrors": [ - { - "errorRef": "PubSub Topic not found", - "end": { - "produceEvents": [ - { - "eventRef": "TopicError", - "data": { "message": "PubSub Topic not found"} - } - ] - } - }, - { - "errorRef": "Error authenticating to PubSub", - "end": { - "produceEvents": [ - { - "eventRef": "TopicError", - "data": { "message": "Error authenticating to PubSub"} - } - ] - } - } - ], - "end": true - } - ], - "functions": [ - { - "name": "PublishToTopic", - "operation": "pubsubapi.json#publish" - } - ], - "events": [ - { - "name": "TopicError", - "source": "pubsub.topic.events", - "type": "pubsub/events" - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -{ - "main": { - "steps": [ - { - "read_item": { - "try": { - "call": "http.get", - "args": { - "url": "https://host.com/api" - }, - "result": "api_response" - }, - "retry": { - "predicate": "${custom_predicate}", - "max_retries": 5, - "backoff": { - "initial_delay": 2, - "max_delay": 60, - "multiplier": 2 - } - } - } - }, - { - "last_step": { - "return": "OK" - } - } - ] - }, - "custom_predicate": { - "params": [ - "e" - ], - "steps": [ - { - "what_to_repeat": { - "switch": [ - { - "condition": "${e.code == 500}", - "return": true - } - ] - } - }, - { - "otherwise": { - "return": false - } - } - ] - } -} -``` - - | -- -```json -{ - "id": "errorhandlingwithretries", - "name": "Error Handling with Retries", - "start": "ReadItem", - "specVersion": "0.8", - "states": [ - { - "name": "ReadItem", - "type": "operation", - "actions": [ - { - "functionRef": "ReadItemFromApi", - "retryRef": "ServiceNotAvailableRetryPolicy", - "retryableErrors": ["Service Not Available"] - } - ], - "onErrors": [ - { - "errorRef": "Service Not Available", - "end": true - } - ], - "end": true - } - ], - "functions": [ - { - "name": "ReadItemFromApi", - "operation": "someapi.json#read" - } - ], - "errors": [ - { - "name": "Service Not Available", - "code": "500" - } - ], - "retries": [ - { - "name": "ServiceNotAvailableRetryPolicy", - "maxAttempts": 5, - "delay": "PT2S", - "maxDelay": "PT60S", - "multiplier": 2 - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -{ - "main": { - "steps": [ - { - "first": { - "call": "hello", - "args": { - "input": "Kristof" - }, - "result": "someOutput" - } - }, - { - "second": { - "return": "${someOutput}" - } - } - ] - }, - "hello": { - "params": [ - "input" - ], - "steps": [ - { - "first": { - "return": "${\"Hello \"+input}" - } - } - ] - } -} -``` - - | -- -```json -{ - "id": "callsubflow", - "name": "Call SubFlow", - "start": "CallSub", - "states": [ - { - "name": "CallSub", - "type":"operation", - "actions": [ - { - "subFlowRef": "calledsubflow" - } - ], - "end": true - } - ] -} -``` - - | -
Serverless Workflow | -|
---|---|
- -```json -[ - { - "firstStep": { - "call": "http.get", - "args": { - "url": "https://www.example.com/callA" - }, - "result": "firstResult" - } - }, - { - "whereToJump": { - "switch": [ - { - "condition": "${firstResult.body.SomeField < 10}", - "next": "small" - }, - { - "condition": "${firstResult.body.SomeField < 100}", - "next": "medium" - } - ], - "next": "large" - } - }, - { - "small": { - "call": "http.get", - "args": { - "url": "https://www.example.com/SmallFunc" - }, - "next": "end" - } - }, - { - "medium": { - "call": "http.get", - "args": { - "url": "https://www.example.com/MediumFunc" - }, - "next": "end" - } - }, - { - "large": { - "call": "http.get", - "args": { - "url": "https://www.example.com/LargeFunc" - }, - "next": "end" - } - } -] -``` - - | -- -```json -{ - "id": "databasedconditions", - "name": "Data Based Conditions", - "start": "CallA", - "states": [ - { - "name": "CallA", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionA" - } - ], - "transition": "EvaluateAResults" - }, - { - "name": "EvaluateAResults", - "type": "switch", - "dataConditions": [ - { - "name": "Less than 10", - "condition": "${ .body | .SomeField < 10 }", - "transition": "CallSmall" - }, - { - "name": "Less than 100", - "condition": "${ .body | .SomeField < 100 }", - "transition": "CallMedium" - } - ], - "defaultCondition": { - "transition": "CallLarge" - } - }, - { - "name": "CallSmall", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionSmall" - } - ], - "end": true - }, - { - "name": "CallMedium", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionMedium" - } - ], - "end": true - }, - { - "name": "CallLarge", - "type":"operation", - "actions": [ - { - "functionRef": "callFunctionMedium" - } - ], - "end": true - } - ], - "functions": [ - { - "name": "callFunctionA", - "operation": "myapi.json#calla" - }, - { - "name": "callFunctionSmall", - "operation": "myapi.json#callsmall" - }, - { - "name": "callFunctionMedium", - "operation": "myapi.json#callmedium" - }, - { - "name": "callFunctionLarge", - "operation": "myapi.json#calllarge" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
- -```java -// Workflow implementation -public static class GreetingWorkflowImpl implements GreetingWorkflow { - private final GreetingActivities activities = - Workflow.newActivityStub( - GreetingActivities.class, - ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofSeconds(2)).build()); - - // Workflow method - @Override - public String getGreeting(String name) { - return activities.composeGreeting("Hello", name); - } -} -``` - - | -- -```json -{ - "id": "greetingworkflow", - "name": "Greeting Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "states": [ - { - "name": "Greet", - "type": "operation", - "actions": [ - { - "name": "Greet Action", - "functionRef": { - "refName": "GreetingFunction", - "arguments": { - "prefix": "Hello", - "name": "${ .name }" - } - } - } - ], - "timeouts": { - "actionExecTimeout": "PT2S" - }, - "end": true - } - ], - "functions": [ - { - "name": "GreetingFunction", - "operation": "myactionsapi.json#composeGreeting" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
- -```java -// Workflow implementation -public static class GreetingWorkflowImpl implements GreetingWorkflow { - private final GreetingActivities activities = - Workflow.newActivityStub( - GreetingActivities.class, - ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofSeconds(10)).build()); - - @Override - public String greet(String name) { - activities.greet("Hello " + name + "!"); - } -} - -// Client code Workflow Options (cron) -WorkflowOptions workflowOptions = - WorkflowOptions.newBuilder() - .setWorkflowId(CRON_WORKFLOW_ID) - .setTaskQueue(TASK_QUEUE) - .setCronSchedule("* * * * *") - .setWorkflowExecutionTimeout(Duration.ofMinutes(10)) - .build(); - -``` - - | -- -```json -{ - "id": "greetingworkflow", - "name": "Greeting Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "timeouts": { - "workflowExecTimeout": "PT10M" - } - "start": { - "stateName": "GreetingState", - "schedule": { - "cron": { - "expression": "* * * * *" - } - } - }, - "states": [ - { - "name": "GreetingState", - "type": "operation", - "actions": [ - { - "name": "Greet", - "functionRef": { - "refName": "GreetingFunction", - "arguments": { - "prefix": "Hello", - "name": "${ .name }" - } - } - } - ], - "timeouts": { - "actionExecTimeout": "PT2S" - }, - "end": true - } - ], - "functions": [ - { - "name": "GreetingFunction", - "operation": "myactionsapi.json#greet" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
-
-```java
-// Workflow implementation
- public static class SagaWorkflowImpl implements SagaWorkflow {
- ActivityOperation activity =
- Workflow.newActivityStub(
- ActivityOperation.class,
- ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofSeconds(2)).build());
-
- // Workflow Method
- @Override
- public void execute() {
- Saga saga = new Saga(new Saga.Options.Builder().setParallelCompensation(false).build());
- try {
- // The following demonstrate how to compensate sync invocations.
- ChildWorkflowOperation op1 = Workflow.newChildWorkflowStub(ChildWorkflowOperation.class);
- op1.execute(10);
- ChildWorkflowCompensation c1 =
- Workflow.newChildWorkflowStub(ChildWorkflowCompensation.class);
- saga.addCompensation(c1::compensate, -10);
-
- // The following demonstrate how to compensate async invocations.
- Promise |
-- -```json -{ - "id": "HelloSaga", - "name": "Hello SAGA compensation Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "states": [ - { - "name": "ExecuteState", - "type": "operation", - "compensatedBy": "CompensateState", - "actions": [ - { - "name": "Execute", - "functionRef": { - "refName": "ExecuteFunction", - "arguments": { - "amount": 10 - } - } - } - ], - "end": { - "compensate": true - } - }, - { - "name": "CompensateState", - "type": "operation", - "usedForCompensation": true, - "actions": [ - { - "name": "Compensate", - "functionRef": { - "refName": "CompensateFunction", - "arguments": { - "amount": -10 - } - } - } - ] - } - ], - "functions": [ - { - "name": "ExecuteFunction", - "operation": "myactionsapi.json#execute" - }, - { - "name": "CompensateFunction", - "operation": "myactionsapi.json#compensate" - } - ] -} -``` - - | -
Temporal | -Serverless Workflow | -
---|---|
- -```java -// Workflow Implementation -public static class GreetingWorkflowImpl implements GreetingWorkflow { - private final GreetingActivities activities = - Workflow.newActivityStub( - GreetingActivities.class, - ActivityOptions.newBuilder() - .setScheduleToCloseTimeout(Duration.ofSeconds(10)) - .setRetryOptions( - RetryOptions.newBuilder() - .setInitialInterval(Duration.ofSeconds(1)) - .setDoNotRetry(IllegalArgumentException.class.getName()) - .build()) - .build()); - @Override - public String getGreeting(String name) { - // This is a blocking call that returns only after activity is completed. - return activities.composeGreeting("Hello", name); - } -} - -// Activity Implementation -static class GreetingActivitiesImpl implements GreetingActivities { - private int callCount; - private long lastInvocationTime; - - @Override - public synchronized String composeGreeting(String greeting, String name) { - if (lastInvocationTime != 0) { - long timeSinceLastInvocation = System.currentTimeMillis() - lastInvocationTime; - System.out.print(timeSinceLastInvocation + " milliseconds since last invocation. "); - } - lastInvocationTime = System.currentTimeMillis(); - if (++callCount < 4) { - System.out.println("composeGreeting activity is going to fail"); - throw new IllegalStateException("not yet"); - } - System.out.println("composeGreeting activity is going to complete"); - return greeting + " " + name + "!"; - } -} -``` - - | -- -```json -{ - "id": "HelloActivityRetry", - "name": "Hello Activity with Retries Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "start": "GreetingState", - "states": [ - { - "name": "GreetingState", - "type": "operation", - "actions": [ - { - "name": "Greet", - "functionRef": { - "refName": "GreetingFunction", - "arguments": { - "name": "World" - }, - "retryRef": "GreetingRetry", - "nonRetryableErrors": ["IllegalArgumentException"] - } - } - ], - "timeouts": { - "actionExecTimeout": "PT10S" - }, - "onErrors": [ - { - "errorRefs": ["IllegalStateException", "IllegalArgumentException"], - "end": true - } - ], - "end": true - } - ], - "functions": [ - { - "name": "GreetingFunction", - "operation": "myactionsapi.json#composeGreeting" - } - ], - "errors": [ - { - "name": "IllegalStateException" - }, - { - "name": "IllegalArgumentException" - } - ], - "retries": [ - { - "name": "GreetingRetry", - "delay": "PT1S" - } - ] -} -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "helloworld", - "version": "1.0.0", - "specVersion": "0.8", - "name": "Hello World Workflow", - "description": "Inject Hello World", - "start": "hello-state", - "states": [ - { - "name": "hello-state", - "type": "inject", - "data": { - "result": "Hello World!" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: helloworld -version: 1.0.0 -specVersion: "0.8" -name: Hello World Workflow -description: Inject Hello World -start: hello-state -states: - - name: hello-state - type: inject - data: - result: Hello World! - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "greeting", - "version": "1.0.0", - "specVersion": "0.8", - "name": "greeting-workflow", - "description": "Greet Someone", - "start": "greet", - "functions": [ - { - "name": "greeting-function", - "type": "openapi", - "operation": "file://myapis/greetingapis.json#greeting" - } - ], - "states": [ - { - "name": "greet", - "type": "operation", - "actions": [ - { - "name": "greet-action", - "functionRef": { - "refName": "greeting-function", - "arguments": { - "name": "${ .person.name }" - } - }, - "actionDataFilter": { - "results": "${ {greeting: .greeting} }" - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: greeting -version: 1.0.0 -specVersion: "0.8" -name: greeting-workflow -description: Greet Someone -start: greet -functions: - - name: greeting-function - type: openapi - operation: file://myapis/greetingapis.json#greeting -states: - - name: greet - type: operation - actions: - - name: greet-action - functionRef: - refName: greeting-function - arguments: - name: ${ .person.name } - actionDataFilter: - results: "${ {greeting: .greeting} }" - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "eventbasedgreeting", - "version": "1.0.0", - "specVersion": "0.8", - "name": "Event Based Greeting Workflow", - "description": "Event Based Greeting", - "start": "greet", - "events": [ - { - "name": "greeting-event", - "type": "greetingEventType", - "source": "greetingEventSource" - } - ], - "functions": [ - { - "name": "greeting-function", - "operation": "file://myapis/greetingapis.json#greeting" - } - ], - "states": [ - { - "name": "greet", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "greeting-event" - ], - "eventDataFilter": { - "data": "${ .greet }", - "toStateData": "${ .greet }" - }, - "actions": [ - { - "name": "greet-action", - "functionRef": { - "refName": "greeting-function", - "arguments": { - "name": "${ .greet.name }" - } - } - } - ] - } - ], - "stateDataFilter": { - "output": "${ .payload.greeting }" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: eventbasedgreeting -version: 1.0.0 -specVersion: "0.8" -name: Event Based Greeting Workflow -description: Event Based Greeting -start: greet -events: - - name: greeting-event - type: greetingEventType - source: greetingEventSource -functions: - - name: greeting-function - operation: file://myapis/greetingapis.json#greeting -states: - - name: greet - type: event - onEvents: - - eventRefs: - - greeting-event - eventDataFilter: - data: ${ .greet } - toStateData: ${ .greet } - actions: - - name: greet-action - functionRef: - refName: greeting-function - arguments: - name: ${ .greet.name } - stateDataFilter: - output: ${ .payload.greeting } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "solvemathproblems", - "version": "1.0.0", - "specVersion": "0.8", - "name": "solve-math-problems-workflow", - "description": "Solve math problems", - "start": "solve", - "functions": [ - { - "name": "solve-math-exp-func", - "operation": "http://myapis.org/mapthapis.json#solveExpression" - } - ], - "states": [ - { - "name": "solve", - "type": "foreach", - "inputCollection": "${ .expressions }", - "iterationParam": "singleexpression", - "outputCollection": "${ .results }", - "actions": [ - { - "name": "solve-action", - "functionRef": { - "refName": "solve-math-exp-func", - "arguments": { - "expression": "${ .singleexpression }" - } - } - } - ], - "stateDataFilter": { - "output": "${ .results }" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: solvemathproblems -version: 1.0.0 -specVersion: "0.8" -name: solve-math-problems-workflow -description: Solve math problems -start: solve -functions: - - name: solve-math-exp-func - operation: http://myapis.org/mapthapis.json#solveExpression -states: - - name: solve - type: foreach - inputCollection: ${ .expressions } - iterationParam: singleexpression - outputCollection: ${ .results } - actions: - - name: solve-action - functionRef: - refName: solve-math-exp-func - arguments: - expression: ${ .singleexpression } - stateDataFilter: - output: ${ .results } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "parallelexec", - "version": "1.0.0", - "specVersion": "0.8", - "name": "parallel-execution", - "description": "Executes two branches in parallel", - "start": "parallelexec", - "states": [ - { - "name": "parallelexec", - "type": "parallel", - "completionType": "allOf", - "branches": [ - { - "name": "short-delay-branch", - "actions": [ - { - "name": "short-delay-action", - "subFlowRef": "shortdelayworkflowid" - } - ] - }, - { - "name": "long-delay-branch", - "actions": [ - { - "name": "short-delay-action", - "subFlowRef": "longdelayworkflowid" - } - ] - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: parallelexec -version: 1.0.0 -specVersion: "0.8" -name: parallel-execution -description: Executes two branches in parallel -start: parallelexec -states: - - name: parallelexec - type: parallel - completionType: allOf - branches: - - name: short-delay-branch - actions: - - name: short-delay-action - subFlowRef: shortdelayworkflowid - - name: long-delay-branch - actions: - - name: short-delay-action - subFlowRef: longdelayworkflowid - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "sendcustomeremail", - "version": "1.0.0", - "specVersion": "0.8", - "name": "send-customer-email-workflow", - "description": "Send email to a customer", - "start": "send-email", - "functions": [ - { - "name": "email-function", - "operation": "file://myapis/emailapis.json#sendEmail" - } - ], - "states": [ - { - "name": "send-email", - "type": "operation", - "actions": [ - { - "name": "send-email-action", - "functionRef": { - "invoke": "async", - "refName": "email-function", - "arguments": { - "customer": "${ .customer }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: sendcustomeremail -version: 1.0.0 -specVersion: "0.8" -name: send-customer-email-workflow -description: Send email to a customer -start: send-email -functions: - - name: email-function - operation: file://myapis/emailapis.json#sendEmail -states: - - name: send-email - type: operation - actions: - - name: send-email-action - functionRef: - invoke: async - refName: email-function - arguments: - customer: ${ .customer } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "onboardcustomer", - "version": "1.0.0", - "specVersion": "0.8", - "name": "onboard-customer", - "description": "Onboard a Customer", - "start": "onboard", - "states": [ - { - "name": "onboard", - "type": "operation", - "actions": [ - { - "name": "onboard-action", - "subFlowRef": { - "invoke": "async", - "onParentComplete": "continue", - "workflowId": "customeronboardingworkflow", - "version": "1.0.0" - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: onboardcustomer -version: 1.0.0 -specVersion: "0.8" -name: onboard-customer -description: Onboard a Customer -start: onboard -states: - - name: onboard - type: operation - actions: - - name: onboard-action - subFlowRef: - invoke: async - onParentComplete: continue - workflowId: customeronboardingworkflow - version: 1.0.0 - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "eventbasedswitchstate", - "version": "1.0.0", - "specVersion": "0.8", - "name": "event-based-switch-transitions", - "description": "Event Based Switch Transitions", - "start": "checkvisastatus", - "events": [ - { - "name": "visa-approved-event", - "type": "VisaApproved", - "source": "visaCheckSource" - }, - { - "name": "visa-rejected-event", - "type": "VisaRejected", - "source": "visaCheckSource" - } - ], - "states": [ - { - "name": "checkvisastatus", - "type": "switch", - "eventConditions": [ - { - "eventRef": "visa-approved-event", - "transition": "handle-approved-visa", - "name": "approved-condition" - }, - { - "eventRef": "visa-rejected-event", - "transition": "handle-rejected-visa", - "name": "rejected-condition" - } - ], - "timeouts": { - "eventTimeout": "PT1H" - }, - "defaultCondition": { - "transition": "handle-no-visa-decision" - } - }, - { - "name": "handle-approved-visa", - "type": "operation", - "actions": [ - { - "name": "handle-approved-action", - "subFlowRef": "handleApprovedVisaWorkflowID" - } - ], - "end": true - }, - { - "name": "handle-rejected-visa", - "type": "operation", - "actions": [ - { - "name": "handle-rejected-action", - "subFlowRef": "handleRejectedVisaWorkflowID" - } - ], - "end": true - }, - { - "name": "handle-no-visa-decision", - "type": "operation", - "actions": [ - { - "name": "handle-novisa-action", - "subFlowRef": "handleNoVisaDecisionWorkflowId" - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: eventbasedswitchstate -version: 1.0.0 -specVersion: "0.8" -name: event-based-switch-transitions -description: Event Based Switch Transitions -start: checkvisastatus -events: - - name: visa-approved-event - type: VisaApproved - source: visaCheckSource - - name: visa-rejected-event - type: VisaRejected - source: visaCheckSource -states: - - name: checkvisastatus - type: switch - eventConditions: - - eventRef: visa-approved-event - transition: handle-approved-visa - name: approved-condition - - eventRef: visa-rejected-event - transition: handle-rejected-visa - name: rejected-condition - timeouts: - eventTimeout: PT1H - defaultCondition: - transition: handle-no-visa-decision - - name: handle-approved-visa - type: operation - actions: - - name: handle-approved-action - subFlowRef: handleApprovedVisaWorkflowID - end: true - - name: handle-rejected-visa - type: operation - actions: - - name: handle-rejected-action - subFlowRef: handleRejectedVisaWorkflowID - end: true - - name: handle-no-visa-decision - type: operation - actions: - - name: handle-novisa-action - subFlowRef: handleNoVisaDecisionWorkflowId - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "applicantrequest", - "version": "1.0.0", - "specVersion": "0.8", - "name": "applicant-request-decision-workflow", - "description": "Determine if applicant request is valid", - "start": "check-application", - "functions": [ - { - "name": "send-rejection-email-function", - "operation": "http://myapis.org/applicationapi.json#emailRejection" - } - ], - "states": [ - { - "name": "check-application", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .applicants | .age >= 18 }", - "transition": "start-application", - "name": "adult-condition" - }, - { - "condition": "${ .applicants | .age < 18 }", - "transition": "reject-application", - "name": "minor-condition" - } - ], - "defaultCondition": { - "transition": "reject-application" - } - }, - { - "name": "start-application", - "type": "operation", - "actions": [ - { - "name": "start-app-action", - "subFlowRef": "startApplicationWorkflowId" - } - ], - "end": true - }, - { - "name": "reject-application", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "send-reject-action", - "functionRef": { - "refName": "send-rejection-email-function", - "arguments": { - "applicant": "${ .applicant }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: applicantrequest -version: 1.0.0 -specVersion: "0.8" -name: applicant-request-decision-workflow -description: Determine if applicant request is valid -start: check-application -functions: - - name: send-rejection-email-function - operation: http://myapis.org/applicationapi.json#emailRejection -states: - - name: check-application - type: switch - dataConditions: - - condition: ${ .applicants | .age >= 18 } - transition: start-application - name: adult-condition - - condition: ${ .applicants | .age < 18 } - transition: reject-application - name: minor-condition - defaultCondition: - transition: reject-application - - name: start-application - type: operation - actions: - - name: start-app-action - subFlowRef: startApplicationWorkflowId - end: true - - name: reject-application - type: operation - actionMode: sequential - actions: - - name: send-reject-action - functionRef: - refName: send-rejection-email-function - arguments: - applicant: ${ .applicant } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "provisionorders", - "version": "1.0.0", - "specVersion": "0.8", - "name": "provision-orders", - "description": "Provision Orders and handle errors thrown", - "start": "provision-order", - "functions": [ - { - "name": "provision-order-function", - "operation": "http://myapis.org/provisioningapi.json#doProvision" - } - ], - "errors": [ - { - "name": "missing-order-id" - }, - { - "name": "missing-order-item" - }, - { - "name": "missing-order-quantity" - } - ], - "states": [ - { - "name": "provision-order", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "provision-action", - "functionRef": { - "refName": "provision-order-function", - "arguments": { - "order": "${ .order }" - } - } - } - ], - "stateDataFilter": { - "output": "${ .exceptions }" - }, - "transition": "apply-order", - "onErrors": [ - { - "errorRef": "missing-order-id", - "transition": "missing-id" - }, - { - "errorRef": "missing-order-item", - "transition": "missing-item" - }, - { - "errorRef": "missing-order-quantity", - "transition": "missing-quantity" - } - ] - }, - { - "name": "missing-id", - "type": "operation", - "actions": [ - { - "name": "missing-action", - "subFlowRef": "handleMissingIdExceptionWorkflow" - } - ], - "end": true - }, - { - "name": "missing-item", - "type": "operation", - "actions": [ - { - "name": "missing-item", - "subFlowRef": "handleMissingItemExceptionWorkflow" - } - ], - "end": true - }, - { - "name": "missing-quantity", - "type": "operation", - "actions": [ - { - "name": "missing-quantity", - "subFlowRef": "handleMissingQuantityExceptionWorkflow" - } - ], - "end": true - }, - { - "name": "apply-order", - "type": "operation", - "actions": [ - { - "name": "apply-order", - "subFlowRef": "applyOrderWorkflowId" - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: provisionorders -version: 1.0.0 -specVersion: "0.8" -name: provision-orders -description: Provision Orders and handle errors thrown -start: provision-order -functions: - - name: provision-order-function - operation: http://myapis.org/provisioningapi.json#doProvision -errors: - - name: missing-order-id - - name: missing-order-item - - name: missing-order-quantity -states: - - name: provision-order - type: operation - actionMode: sequential - actions: - - name: provision-action - functionRef: - refName: provision-order-function - arguments: - order: ${ .order } - stateDataFilter: - output: ${ .exceptions } - transition: apply-order - onErrors: - - errorRef: missing-order-id - transition: missing-id - - errorRef: missing-order-item - transition: missing-item - - errorRef: missing-order-quantity - transition: missing-quantity - - name: missing-id - type: operation - actions: - - name: missing-action - subFlowRef: handleMissingIdExceptionWorkflow - end: true - - name: missing-item - type: operation - actions: - - name: missing-item - subFlowRef: handleMissingItemExceptionWorkflow - end: true - - name: missing-quantity - type: operation - actions: - - name: missing-quantity - subFlowRef: handleMissingQuantityExceptionWorkflow - end: true - - name: apply-order - type: operation - actions: - - name: apply-order - subFlowRef: applyOrderWorkflowId - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "jobmonitoring", - "version": "1.0.0", - "specVersion": "0.8", - "name": "jobmonitoring", - "description": "Monitor finished execution of a submitted job", - "start": "submit-job", - "functions": [ - { - "name": "submit-job", - "operation": "http://myapis.org/monitorapi.json#doSubmit" - }, - { - "name": "check-job-status", - "operation": "http://myapis.org/monitorapi.json#checkStatus" - }, - { - "name": "report-job-suceeded", - "operation": "http://myapis.org/monitorapi.json#reportSucceeded" - }, - { - "name": "report-job-failed", - "operation": "http://myapis.org/monitorapi.json#reportFailure" - } - ], - "states": [ - { - "name": "submit-job", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "submit-job", - "functionRef": { - "refName": "submit-job", - "arguments": { - "name": "${ .job.name }" - } - }, - "actionDataFilter": { - "results": "${ .jobuid }" - } - } - ], - "stateDataFilter": { - "output": "${ .jobuid }" - }, - "transition": "wait-for-completion" - }, - { - "name": "wait-for-completion", - "type": "sleep", - "duration": "PT5S", - "transition": "get-job-status" - }, - { - "name": "get-job-status", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "get-job-status", - "functionRef": { - "refName": "check-job-status", - "arguments": { - "name": "${ .jobuid }" - } - }, - "actionDataFilter": { - "results": "${ .jobstatus }" - } - } - ], - "stateDataFilter": { - "output": "${ .jobstatus }" - }, - "transition": "determine-completion" - }, - { - "name": "determine-completion", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .jobStatus == \"SUCCEEDED\" }", - "transition": "job-succeeded", - "name": "succeed" - }, - { - "condition": "${ .jobStatus == \"FAILED\" }", - "transition": "job-failed", - "name": "failed" - } - ], - "defaultCondition": { - "transition": "wait-for-completion" - } - }, - { - "name": "job-succeeded", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "job-succeeded", - "functionRef": { - "refName": "report-job-suceeded", - "arguments": { - "name": "${ .jobuid }" - } - } - } - ], - "end": true - }, - { - "name": "job-failed", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "job-failed", - "functionRef": { - "refName": "report-job-failed", - "arguments": { - "name": "${ .jobuid }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: jobmonitoring -version: 1.0.0 -specVersion: "0.8" -name: jobmonitoring -description: Monitor finished execution of a submitted job -start: submit-job -functions: - - name: submit-job - operation: http://myapis.org/monitorapi.json#doSubmit - - name: check-job-status - operation: http://myapis.org/monitorapi.json#checkStatus - - name: report-job-suceeded - operation: http://myapis.org/monitorapi.json#reportSucceeded - - name: report-job-failed - operation: http://myapis.org/monitorapi.json#reportFailure -states: - - name: submit-job - type: operation - actionMode: sequential - actions: - - name: submit-job - functionRef: - refName: submit-job - arguments: - name: ${ .job.name } - actionDataFilter: - results: ${ .jobuid } - stateDataFilter: - output: ${ .jobuid } - transition: wait-for-completion - - name: wait-for-completion - type: sleep - duration: PT5S - transition: get-job-status - - name: get-job-status - type: operation - actionMode: sequential - actions: - - name: get-job-status - functionRef: - refName: check-job-status - arguments: - name: ${ .jobuid } - actionDataFilter: - results: ${ .jobstatus } - stateDataFilter: - output: ${ .jobstatus } - transition: determine-completion - - name: determine-completion - type: switch - dataConditions: - - condition: ${ .jobStatus == "SUCCEEDED" } - transition: job-succeeded - name: succeed - - condition: ${ .jobStatus == "FAILED" } - transition: job-failed - name: failed - defaultCondition: - transition: wait-for-completion - - name: job-succeeded - type: operation - actionMode: sequential - actions: - - name: job-succeeded - functionRef: - refName: report-job-suceeded - arguments: - name: ${ .jobuid } - end: true - - name: job-failed - type: operation - actionMode: sequential - actions: - - name: job-failed - functionRef: - refName: report-job-failed - arguments: - name: ${ .jobuid } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "sendcloudeventonprovision", - "version": "1.0.0", - "specVersion": "0.8", - "name": "sendcloudeventonprovision", - "start": "provision-orders-state", - "events": [ - { - "name": "provisioning-complete-event", - "type": "provisionCompleteType", - "kind": "produced" - } - ], - "functions": [ - { - "name": "provision-order-function", - "operation": "http://myapis.org/provisioning.json#doProvision" - } - ], - "states": [ - { - "name": "provision-orders-state", - "type": "foreach", - "inputCollection": "${ .orders }", - "iterationParam": "singleorder", - "outputCollection": "${ .provisionedOrders }", - "actions": [ - { - "name": "provision-order-function", - "functionRef": { - "refName": "provision-order-function", - "arguments": { - "order": "${ .singleorder }" - } - } - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "provisioning-complete-event", - "data": "${ .provisionedOrders }" - } - ] - } - } - ] -}``` - - | -- -```yaml -id: sendcloudeventonprovision -version: 1.0.0 -specVersion: "0.8" -name: sendcloudeventonprovision -start: provision-orders-state -events: - - name: provisioning-complete-event - type: provisionCompleteType - kind: produced -functions: - - name: provision-order-function - operation: http://myapis.org/provisioning.json#doProvision -states: - - name: provision-orders-state - type: foreach - inputCollection: ${ .orders } - iterationParam: singleorder - outputCollection: ${ .provisionedOrders } - actions: - - name: provision-order-function - functionRef: - refName: provision-order-function - arguments: - order: ${ .singleorder } - end: - produceEvents: - - eventRef: provisioning-complete-event - data: ${ .provisionedOrders } -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "patientVitalsWorkflow", - "name": "patientVitalsWorkflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "monitor-vitals", - "events": [ - { - "name": "high-body-temperature", - "type": "org.monitor.highBodyTemp", - "source": "monitoringSource", - "correlation": [ - { - "contextAttributeName": "patientId" - } - ] - }, - { - "name": "high-blood-pressure", - "type": "org.monitor.highBloodPressure", - "source": "monitoringSource", - "correlation": [ - { - "contextAttributeName": "patientId" - } - ] - }, - { - "name": "high-respiration-rate", - "type": "org.monitor.highRespirationRate", - "source": "monitoringSource", - "correlation": [ - { - "contextAttributeName": "patientId" - } - ] - } - ], - "functions": [ - { - "name": "call-pulmonologist", - "operation": "http://myapis.org/patientapis.json#callPulmonologist" - }, - { - "name": "send-tylenol-order", - "operation": "http://myapis.org/patientapis.json#tylenolOrder" - }, - { - "name": "call-nurse", - "operation": "http://myapis.org/patientapis.json#callNurse" - } - ], - "states": [ - { - "name": "monitor-vitals", - "type": "event", - "exclusive": true, - "onEvents": [ - { - "eventRefs": [ - "high-body-temperature" - ], - "actions": [ - { - "name": "send-tylenol-order", - "functionRef": { - "refName": "send-tylenol-order", - "arguments": { - "patientid": "${ .patientId }" - } - } - } - ] - }, - { - "eventRefs": [ - "high-blood-pressure" - ], - "actions": [ - { - "name": "call-nurse", - "functionRef": { - "refName": "call-nurse", - "arguments": { - "patientid": "${ .patientId }" - } - } - } - ] - }, - { - "eventRefs": [ - "high-respiration-rate" - ], - "actions": [ - { - "name": "call-pulmonologist", - "functionRef": { - "refName": "call-pulmonologist", - "arguments": { - "patientid": "${ .patientId }" - } - } - } - ] - } - ], - "end": { - "terminate": true - } - } - ] -}``` - - | -- -```yaml -id: patientVitalsWorkflow -name: patientVitalsWorkflow -version: 1.0.0 -specVersion: "0.8" -start: monitor-vitals -events: - - name: high-body-temperature - type: org.monitor.highBodyTemp - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: high-blood-pressure - type: org.monitor.highBloodPressure - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: high-respiration-rate - type: org.monitor.highRespirationRate - source: monitoringSource - correlation: - - contextAttributeName: patientId -functions: - - name: call-pulmonologist - operation: http://myapis.org/patientapis.json#callPulmonologist - - name: send-tylenol-order - operation: http://myapis.org/patientapis.json#tylenolOrder - - name: call-nurse - operation: http://myapis.org/patientapis.json#callNurse -states: - - name: monitor-vitals - type: event - exclusive: true - onEvents: - - eventRefs: - - high-body-temperature - actions: - - name: send-tylenol-order - functionRef: - refName: send-tylenol-order - arguments: - patientid: ${ .patientId } - - eventRefs: - - high-blood-pressure - actions: - - name: call-nurse - functionRef: - refName: call-nurse - arguments: - patientid: ${ .patientId } - - eventRefs: - - high-respiration-rate - actions: - - name: call-pulmonologist - functionRef: - refName: call-pulmonologist - arguments: - patientid: ${ .patientId } - end: - terminate: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "finalize-college-application", - "name": "finalizeCollegeApplication", - "version": "1.0.0", - "specVersion": "0.8", - "start": "finalize-application", - "events": [ - { - "name": "application-submitted", - "type": "org.application.submitted", - "source": "applicationsource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] - }, - { - "name": "sat-scores-received", - "type": "org.application.satscores", - "source": "applicationsource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] - }, - { - "name": "recommendation-letter-received", - "type": "org.application.recommendationLetter", - "source": "applicationsource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] - } - ], - "functions": [ - { - "name": "finalize-application-function", - "operation": "http://myapis.org/collegeapplicationapi.json#finalize" - } - ], - "states": [ - { - "name": "finalize-application", - "type": "event", - "exclusive": false, - "onEvents": [ - { - "eventRefs": [ - "application-submitted", - "sat-scores-received", - "recommendation-letter-received" - ], - "actions": [ - { - "name": "finalize-application", - "functionRef": { - "refName": "finalize-application-function", - "arguments": { - "student": "${ .applicantId }" - } - } - } - ] - } - ], - "end": { - "terminate": true - } - } - ] -}``` - - | -- -```yaml -id: finalize-college-application -name: finalizeCollegeApplication -version: 1.0.0 -specVersion: "0.8" -start: finalize-application -events: - - name: application-submitted - type: org.application.submitted - source: applicationsource - correlation: - - contextAttributeName: applicantId - - name: sat-scores-received - type: org.application.satscores - source: applicationsource - correlation: - - contextAttributeName: applicantId - - name: recommendation-letter-received - type: org.application.recommendationLetter - source: applicationsource - correlation: - - contextAttributeName: applicantId -functions: - - name: finalize-application-function - operation: http://myapis.org/collegeapplicationapi.json#finalize -states: - - name: finalize-application - type: event - exclusive: false - onEvents: - - eventRefs: - - application-submitted - - sat-scores-received - - recommendation-letter-received - actions: - - name: finalize-application - functionRef: - refName: finalize-application-function - arguments: - student: ${ .applicantId } - end: - terminate: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "customercreditcheck", - "version": "1.0.0", - "specVersion": "0.8", - "name": "customercreditcheck", - "description": "Perform Customer Credit Check", - "start": "check-credit", - "functions": [ - { - "name": "credit-check-function", - "operation": "http://myapis.org/creditcheckapi.json#doCreditCheck" - }, - { - "name": "send-rejection-email-function", - "operation": "http://myapis.org/creditcheckapi.json#rejectionEmail" - } - ], - "events": [ - { - "name": "credit-check-completed-event", - "type": "creditCheckCompleteType", - "source": "creditCheckSource", - "correlation": [ - { - "contextAttributeName": "customerId" - } - ] - } - ], - "states": [ - { - "name": "check-credit", - "type": "callback", - "action": { - "name": "check-credit", - "functionRef": { - "refName": "call-credit-check-microservice", - "arguments": { - "customer": "${ .customer }" - } - } - }, - "eventRef": "credit-check-completed-event", - "timeouts": { - "stateExecTimeout": "PT15M" - }, - "transition": "evaluate-decision" - }, - { - "name": "evaluate-decision", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .creditCheck | .decision == \"Approved\" }", - "transition": "start-application", - "name": "start-application" - }, - { - "condition": "${ .creditCheck | .decision == \"Denied\" }", - "transition": "reject-application", - "name": "reject-application" - } - ], - "defaultCondition": { - "transition": "reject-application" - } - }, - { - "name": "start-application", - "type": "operation", - "actions": [ - { - "name": "start-application", - "subFlowRef": "startApplicationWorkflowId" - } - ], - "end": true - }, - { - "name": "reject-application", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name": "reject-application", - "functionRef": { - "refName": "send-rejection-email-function", - "arguments": { - "applicant": "${ .customer }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: customercreditcheck -version: 1.0.0 -specVersion: "0.8" -name: customercreditcheck -description: Perform Customer Credit Check -start: check-credit -functions: - - name: credit-check-function - operation: http://myapis.org/creditcheckapi.json#doCreditCheck - - name: send-rejection-email-function - operation: http://myapis.org/creditcheckapi.json#rejectionEmail -events: - - name: credit-check-completed-event - type: creditCheckCompleteType - source: creditCheckSource - correlation: - - contextAttributeName: customerId -states: - - name: check-credit - type: callback - action: - name: check-credit - functionRef: - refName: call-credit-check-microservice - arguments: - customer: ${ .customer } - eventRef: credit-check-completed-event - timeouts: - stateExecTimeout: PT15M - transition: evaluate-decision - - name: evaluate-decision - type: switch - dataConditions: - - condition: ${ .creditCheck | .decision == "Approved" } - transition: start-application - name: start-application - - condition: ${ .creditCheck | .decision == "Denied" } - transition: reject-application - name: reject-application - defaultCondition: - transition: reject-application - - name: start-application - type: operation - actions: - - name: start-application - subFlowRef: startApplicationWorkflowId - end: true - - name: reject-application - type: operation - actionMode: sequential - actions: - - name: reject-application - functionRef: - refName: send-rejection-email-function - arguments: - applicant: ${ .customer } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "handle-car-auction-bid", - "version": "1.0.0", - "specVersion": "0.8", - "name": "handle-car-auction-bid", - "description": "Store a single bid whole the car auction is active", - "start": { - "stateName": "store-car-auction-bid", - "schedule": "R/PT2H" - }, - "functions": [ - { - "name": "store-bid-function", - "operation": "http://myapis.org/carauctionapi.json#storeBid" - } - ], - "events": [ - { - "name": "car-bid-event", - "type": "carBidMadeType", - "source": "carBidEventSource" - } - ], - "states": [ - { - "name": "store-car-auction-bid", - "type": "event", - "exclusive": true, - "onEvents": [ - { - "eventRefs": [ - "car-bid-event" - ], - "actions": [ - { - "name": "car-bid-event", - "functionRef": { - "refName": "store-bid-function", - "arguments": { - "bid": "${ .bid }" - } - } - } - ] - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: handle-car-auction-bid -version: 1.0.0 -specVersion: "0.8" -name: handle-car-auction-bid -description: Store a single bid whole the car auction is active -start: - stateName: store-car-auction-bid - schedule: R/PT2H -functions: - - name: store-bid-function - operation: http://myapis.org/carauctionapi.json#storeBid -events: - - name: car-bid-event - type: carBidMadeType - source: carBidEventSource -states: - - name: store-car-auction-bid - type: event - exclusive: true - onEvents: - - eventRefs: - - car-bid-event - actions: - - name: car-bid-event - functionRef: - refName: store-bid-function - arguments: - bid: ${ .bid } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "check-inbox", - "name": "check-inbox", - "version": "1.0.0", - "specVersion": "0.8", - "description": "Periodically Check Inbox", - "start": { - "stateName": "check-inbox", - "schedule": { - "cron": "0 0/15 * * * ?" - } - }, - "functions": [ - { - "name": "check-inbox-function", - "operation": "http://myapis.org/inboxapi.json#checkNewMessages" - }, - { - "name": "send-text-function", - "operation": "http://myapis.org/inboxapi.json#sendText" - } - ], - "states": [ - { - "name": "check-inbox", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "name":"check-inbox", - "functionRef": "check-inbox-function" - } - ], - "transition": "send-text-for-high-priority" - }, - { - "name": "send-text-for-high-priority", - "type": "foreach", - "inputCollection": "${ .messages }", - "iterationParam": "singlemessage", - "actions": [ - { - "name": "send-text-for-high-priority", - "functionRef": { - "refName": "send-text-function", - "arguments": { - "message": "${ .singlemessage }" - } - } - } - ], - "end": true - } - ] -}``` - - | -- -```yaml -id: check-inbox -name: check-inbox -version: 1.0.0 -specVersion: "0.8" -description: Periodically Check Inbox -start: - stateName: check-inbox - schedule: - cron: 0 0/15 * * * ? -functions: - - name: check-inbox-function - operation: http://myapis.org/inboxapi.json#checkNewMessages - - name: send-text-function - operation: http://myapis.org/inboxapi.json#sendText -states: - - name: check-inbox - type: operation - actionMode: sequential - actions: - - name: check-inbox - functionRef: check-inbox-function - transition: send-text-for-high-priority - - name: send-text-for-high-priority - type: foreach - inputCollection: ${ .messages } - iterationParam: singlemessage - actions: - - name: send-text-for-high-priority - functionRef: - refName: send-text-function - arguments: - message: ${ .singlemessage } - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "vet-appointment-workflow", - "name": "vet-appointment-workflow", - "description": "Vet service call via events", - "version": "1.0.0", - "specVersion": "0.8", - "start": "make-vet-appointment-state", - "events": [ - { - "name": "make-vet-appointment", - "source": "VetServiceSource", - "type": "events.vet.appointments", - "kind": "produced" - }, - { - "name": "vet-appointment-info", - "source": "VetServiceSource", - "type": "events.vet.appointments", - "kind": "consumed" - } - ], - "states": [ - { - "name": "make-vet-appointment-state", - "type": "operation", - "actions": [ - { - "name": "make-appointment-action", - "eventRef": { - "produceEventRef": "make-vet-appointment", - "data": "${ .patientInfo }", - "consumeEventRef": "vet-appointment-info" - }, - "actionDataFilter": { - "results": "${ .appointmentInfo }" - } - } - ], - "timeouts": { - "actionExecTimeout": "PT15M" - }, - "end": true - } - ] -}``` - - | -- -```yaml -id: vet-appointment-workflow -name: vet-appointment-workflow -description: Vet service call via events -version: 1.0.0 -specVersion: "0.8" -start: make-vet-appointment-state -events: - - name: make-vet-appointment - source: VetServiceSource - type: events.vet.appointments - kind: produced - - name: vet-appointment-info - source: VetServiceSource - type: events.vet.appointments - kind: consumed -states: - - name: make-vet-appointment-state - type: operation - actions: - - name: make-appointment-action - eventRef: - produceEventRef: make-vet-appointment - data: ${ .patientInfo } - consumeEventRef: vet-appointment-info - actionDataFilter: - results: ${ .appointmentInfo } - timeouts: - actionExecTimeout: PT15M - end: true -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "paymentconfirmation", - "version": "1.0.0", - "specVersion": "0.8", - "name": "paymentconfirmation", - "description": "Performs Payment Confirmation", - "functions": "file://functiondefs.json", - "events": "file://eventdefs.yml", - "states": [ - { - "name": "payment-received", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "payment-received-event" - ], - "actions": [ - { - "name": "checkfunds", - "functionRef": { - "refName": "check-funds-availability", - "arguments": { - "account": "${ .accountId }", - "paymentamount": "${ .payment.amount }" - } - } - } - ] - } - ], - "transition": "confirm-based-on-funds" - }, - { - "name": "confirm-based-on-funds", - "type": "switch", - "dataConditions": [ - { - "condition": "${ .funds | .available == \"true\" }", - "transition": "send-payment-success", - "name": "success" - }, - { - "condition": "${ .funds | .available == \"false\" }", - "transition": "send-insufficient-results", - "name": "failed" - } - ], - "defaultCondition": { - "transition": "send-payment-success" - } - }, - { - "name": "send-payment-success", - "type": "operation", - "actions": [ - { - "name": "send-payment-success", - "functionRef": { - "refName": "send-success-email", - "arguments": { - "applicant": "${ .customer }" - } - } - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "confirmation-completed-event", - "data": "${ .payment }" - } - ] - } - }, - { - "name": "send-insufficient-results", - "type": "operation", - "actions": [ - { - "name": "send-insufficient-results", - "functionRef": { - "refName": "send-insufficient-funds-email", - "arguments": { - "applicant": "${ .customer }" - } - } - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "confirmation-completed-event", - "data": "${ .payment }" - } - ] - } - } - ] -}``` - - | -- -```yaml -id: paymentconfirmation -version: 1.0.0 -specVersion: "0.8" -name: paymentconfirmation -description: Performs Payment Confirmation -functions: file://functiondefs.json -events: file://eventdefs.yml -states: - - name: payment-received - type: event - onEvents: - - eventRefs: - - payment-received-event - actions: - - name: checkfunds - functionRef: - refName: check-funds-availability - arguments: - account: ${ .accountId } - paymentamount: ${ .payment.amount } - transition: confirm-based-on-funds - - name: confirm-based-on-funds - type: switch - dataConditions: - - condition: ${ .funds | .available == "true" } - transition: send-payment-success - name: success - - condition: ${ .funds | .available == "false" } - transition: send-insufficient-results - name: failed - defaultCondition: - transition: send-payment-success - - name: send-payment-success - type: operation - actions: - - name: send-payment-success - functionRef: - refName: send-success-email - arguments: - applicant: ${ .customer } - end: - produceEvents: - - eventRef: confirmation-completed-event - data: ${ .payment } - - name: send-insufficient-results - type: operation - actions: - - name: send-insufficient-results - functionRef: - refName: send-insufficient-funds-email - arguments: - applicant: ${ .customer } - end: - produceEvents: - - eventRef: confirmation-completed-event - data: ${ .payment } -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "patientonboarding", - "name": "patientonboarding", - "version": "1.0.0", - "specVersion": "0.8", - "start": "onboard", - "states": [ - { - "name": "onboard", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "new-patient-event" - ], - "actions": [ - { - "name": "store-patient", - "functionRef": "store-patient", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] - }, - { - "name": "assign-doctor", - "functionRef": "assign-doctor", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] - }, - { - "name": "schedule-appt", - "functionRef": "schedule-appt", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] - } - ] - } - ], - "onErrors": [ - { - "errorRef": "service-not-available", - "end": true - } - ], - "end": true - } - ], - "events": [ - { - "name": "store-patient", - "type": "new.patients.event", - "source": "newpatient/+" - } - ], - "functions": [ - { - "name": "store-new-patient-info", - "operation": "api/services.json#addPatient" - }, - { - "name": "assign-doctor", - "operation": "api/services.json#assignDoctor" - }, - { - "name": "schedule-appt", - "operation": "api/services.json#scheduleAppointment" - } - ], - "errors": [ - { - "name": "service-not-available", - "code": "503" - } - ], - "retries": [ - { - "name": "services-not-available-retry-strategy", - "delay": "PT3S", - "maxAttempts": 10 - } - ] -}``` - - | -- -```yaml -id: patientonboarding -name: patientonboarding -version: 1.0.0 -specVersion: "0.8" -start: onboard -states: - - name: onboard - type: event - onEvents: - - eventRefs: - - new-patient-event - actions: - - name: store-patient - functionRef: store-patient - retryRef: services-not-available-retry-strategy - retryableErrors: - - service-not-available - - name: assign-doctor - functionRef: assign-doctor - retryRef: services-not-available-retry-strategy - retryableErrors: - - service-not-available - - name: schedule-appt - functionRef: schedule-appt - retryRef: services-not-available-retry-strategy - retryableErrors: - - service-not-available - onErrors: - - errorRef: service-not-available - end: true - end: true -events: - - name: store-patient - type: new.patients.event - source: newpatient/+ -functions: - - name: store-new-patient-info - operation: api/services.json#addPatient - - name: assign-doctor - operation: api/services.json#assignDoctor - - name: schedule-appt - operation: api/services.json#scheduleAppointment -errors: - - name: service-not-available - code: "503" -retries: - - name: services-not-available-retry-strategy - delay: PT3S - maxAttempts: 10 -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "order", - "name": "order", - "description": "Purchase Order Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "start-new-order", - "timeouts": { - "workflowExecTimeout": { - "duration": "PT30D", - "runBefore": "CancelOrder" - } - }, - "states": [ - { - "name": "start-new-order", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "order-created-event" - ], - "actions": [ - { - "name": "log-new-order-created", - "functionRef": { - "refName": "log-new-order-created" - } - } - ] - } - ], - "transition": { - "nextState": "wait-for-order-confirmation" - } - }, - { - "name": "wait-for-order-confirmation", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "order-confirmed-event" - ], - "actions": [ - { - "name": "log-order-confirmed", - "functionRef": { - "refName": "log-order-confirmed" - } - } - ] - } - ], - "transition": { - "nextState": "wait-order-shipped" - } - }, - { - "name": "wait-order-shipped", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "shipment-sent-event" - ], - "actions": [ - { - "name": "log-order-shipped", - "functionRef": { - "refName": "log-order-shipped" - } - } - ] - } - ], - "end": { - "terminate": true, - "produceEvents": [ - { - "eventRef": "order-finished-event" - } - ] - } - }, - { - "name": "cancel-order", - "type": "operation", - "actions": [ - { - "name": "cancel-order", - "functionRef": { - "refName": "cancel-order" - } - } - ], - "end": { - "terminate": true, - "produceEvents": [ - { - "eventRef": "order-cancelled-event" - } - ] - } - } - ], - "events": [ - { - "name": "order-created-event", - "type": "my.company.orders", - "source": "/orders/new", - "correlation": [ - { - "contextAttributeName": "orderid" - } - ] - }, - { - "name": "order-confirmed-event", - "type": "my.company.orders", - "source": "/orders/confirmed", - "correlation": [ - { - "contextAttributeName": "orderid" - } - ] - }, - { - "name": "shipment-sent-event", - "type": "my.company.orders", - "source": "/orders/shipped", - "correlation": [ - { - "contextAttributeName": "orderid" - } - ] - }, - { - "name": "order-finished-event", - "type": "my.company.orders", - "kind": "produced" - }, - { - "name": "order-cancelled-event", - "type": "my.company.orders", - "kind": "produced" - } - ], - "functions": [ - { - "name": "log-new-order-created", - "operation": "http.myorg.io/ordersservices.json#logcreated" - }, - { - "name": "log-order-confirmed", - "operation": "http.myorg.io/ordersservices.json#logconfirmed" - }, - { - "name": "log-order-shipped", - "operation": "http.myorg.io/ordersservices.json#logshipped" - }, - { - "name": "cancel-order", - "operation": "http.myorg.io/ordersservices.json#calcelorder" - } - ] -}``` - - | -- -```yaml -id: order -name: order -description: Purchase Order Workflow -version: 1.0.0 -specVersion: "0.8" -start: start-new-order -timeouts: - workflowExecTimeout: - duration: PT30D - runBefore: CancelOrder -states: - - name: start-new-order - type: event - onEvents: - - eventRefs: - - order-created-event - actions: - - name: log-new-order-created - functionRef: - refName: log-new-order-created - transition: - nextState: wait-for-order-confirmation - - name: wait-for-order-confirmation - type: event - onEvents: - - eventRefs: - - order-confirmed-event - actions: - - name: log-order-confirmed - functionRef: - refName: log-order-confirmed - transition: - nextState: wait-order-shipped - - name: wait-order-shipped - type: event - onEvents: - - eventRefs: - - shipment-sent-event - actions: - - name: log-order-shipped - functionRef: - refName: log-order-shipped - end: - terminate: true - produceEvents: - - eventRef: order-finished-event - - name: cancel-order - type: operation - actions: - - name: cancel-order - functionRef: - refName: cancel-order - end: - terminate: true - produceEvents: - - eventRef: order-cancelled-event -events: - - name: order-created-event - type: my.company.orders - source: /orders/new - correlation: - - contextAttributeName: orderid - - name: order-confirmed-event - type: my.company.orders - source: /orders/confirmed - correlation: - - contextAttributeName: orderid - - name: shipment-sent-event - type: my.company.orders - source: /orders/shipped - correlation: - - contextAttributeName: orderid - - name: order-finished-event - type: my.company.orders - kind: produced - - name: order-cancelled-event - type: my.company.orders - kind: produced -functions: - - name: log-new-order-created - operation: http.myorg.io/ordersservices.json#logcreated - - name: log-order-confirmed - operation: http.myorg.io/ordersservices.json#logconfirmed - - name: log-order-shipped - operation: http.myorg.io/ordersservices.json#logshipped - - name: cancel-order - operation: http.myorg.io/ordersservices.json#calcelorder -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "roomreadings", - "name": "roomreadings", - "description": "Room Temp and Humidity Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "consume-reading", - "timeouts": { - "workflowExecTimeout": { - "duration": "PT1H", - "runBefore": "generate-report" - } - }, - "keepActive": true, - "states": [ - { - "name": "consume-reading", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "temperature-event", - "humidity-event" - ], - "actions": [ - { - "name": "log-reading", - "functionRef": { - "refName": "log-reading" - } - } - ], - "eventDataFilter": { - "toStateData": "${ .readings }" - } - } - ], - "end": true - }, - { - "name": "generate-report", - "type": "operation", - "actions": [ - { - "name": "generate-report", - "functionRef": { - "refName": "produce-report", - "arguments": { - "data": "${ .readings }" - } - } - } - ], - "end": { - "terminate": true - } - } - ], - "events": [ - { - "name": "temperature-event", - "type": "my.home.sensors", - "source": "/home/rooms/+", - "correlation": [ - { - "contextAttributeName": "roomId" - } - ] - }, - { - "name": "humidity-event", - "type": "my.home.sensors", - "source": "/home/rooms/+", - "correlation": [ - { - "contextAttributeName": "roomId" - } - ] - } - ], - "functions": [ - { - "name": "log-reading", - "operation": "http.myorg.io/ordersservices.json#logreading" - }, - { - "name": "produce-report", - "operation": "http.myorg.io/ordersservices.json#produceReport" - } - ] -}``` - - | -- -```yaml -id: roomreadings -name: roomreadings -description: Room Temp and Humidity Workflow -version: 1.0.0 -specVersion: "0.8" -start: consume-reading -timeouts: - workflowExecTimeout: - duration: PT1H - runBefore: generate-report -keepActive: true -states: - - name: consume-reading - type: event - onEvents: - - eventRefs: - - temperature-event - - humidity-event - actions: - - name: log-reading - functionRef: - refName: log-reading - eventDataFilter: - toStateData: ${ .readings } - end: true - - name: generate-report - type: operation - actions: - - name: generate-report - functionRef: - refName: produce-report - arguments: - data: ${ .readings } - end: - terminate: true -events: - - name: temperature-event - type: my.home.sensors - source: /home/rooms/+ - correlation: - - contextAttributeName: roomId - - name: humidity-event - type: my.home.sensors - source: /home/rooms/+ - correlation: - - contextAttributeName: roomId -functions: - - name: log-reading - operation: http.myorg.io/ordersservices.json#logreading - - name: produce-report - operation: http.myorg.io/ordersservices.json#produceReport -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "checkcarvitals", - "name": "checkcarvitals", - "description": "Check Car Vitals Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "when-car-is-on", - "states": [ - { - "name": "when-car-is-on", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "car-turned-on-event" - ] - } - ], - "transition": "do-car-vital-checks" - }, - { - "name": "do-car-vital-checks", - "type": "operation", - "actions": [ - { - "name": "do-car-vital-checks", - "subFlowRef": "vitalscheck", - "sleep": { - "after": "PT1S" - } - } - ], - "transition": "check-continue-vital-checks" - }, - { - "name": "check-continue-vital-checks", - "type": "switch", - "eventConditions": [ - { - "name": "car-turned-off-condition", - "eventRef": "car-turned-off-event", - "end": true - } - ], - "defaultCondition": { - "transition": "do-car-vital-checks" - } - } - ], - "events": [ - { - "name": "car-turned-on-event", - "type": "car.events", - "source": "my/car" - }, - { - "name": "car-turned-off-event", - "type": "car.events", - "source": "my/car" - } - ] -}``` - - | -- -```yaml -id: checkcarvitals -name: checkcarvitals -description: Check Car Vitals Workflow -version: 1.0.0 -specVersion: "0.8" -start: when-car-is-on -states: - - name: when-car-is-on - type: event - onEvents: - - eventRefs: - - car-turned-on-event - transition: do-car-vital-checks - - name: do-car-vital-checks - type: operation - actions: - - name: do-car-vital-checks - subFlowRef: vitalscheck - sleep: - after: PT1S - transition: check-continue-vital-checks - - name: check-continue-vital-checks - type: switch - eventConditions: - - name: car-turned-off-condition - eventRef: car-turned-off-event - end: true - defaultCondition: - transition: do-car-vital-checks -events: - - name: car-turned-on-event - type: car.events - source: my/car - - name: car-turned-off-event - type: car.events - source: my/car -``` - - | -
JSON | -YAML | -|
---|---|---|
- -```json -{ - "id": "vitalscheck", - "name": "vitalscheck", - "description": "Car Vitals Check", - "version": "1.0.0", - "specVersion": "0.8", - "start": "check-vitals", - "states": [ - { - "name": "check-vitals", - "type": "operation", - "actions": [ - { - "name": "check-tire-pressure", - "functionRef": "check-tire-pressure" - }, - { - "name": "check-oil-pressure", - "functionRef": "check-oil-pressure" - }, - { - "name": "check-coolant-level", - "functionRef": "check-coolant-level" - }, - { - "name": "check-battery", - "functionRef": "check-battery" - } - ], - "end": { - "produceEvents": [ - { - "eventRef": "display-checks-on-dashboard", - "data": "${ .evaluations }" - } - ] - } - } - ], - "functions": [ - { - "name": "check-tire-pressure", - "operation": "mycarservices.json#checktirepressure" - }, - { - "name": "check-oil-pressure", - "operation": "mycarservices.json#checkoilpressure" - }, - { - "name": "check-coolant-level", - "operation": "mycarservices.json#checkcoolantlevel" - }, - { - "name": "check-battery", - "operation": "mycarservices.json#checkbattery" - } - ] -}``` - - | -- -```yaml -id: vitalscheck -name: vitalscheck -description: Car Vitals Check -version: 1.0.0 -specVersion: "0.8" -start: check-vitals -states: - - name: check-vitals - type: operation - actions: - - name: check-tire-pressure - functionRef: check-tire-pressure - - name: check-oil-pressure - functionRef: check-oil-pressure - - name: check-coolant-level - functionRef: check-coolant-level - - name: check-battery - functionRef: check-battery - end: - produceEvents: - - eventRef: display-checks-on-dashboard - data: ${ .evaluations } -functions: - - name: check-tire-pressure - operation: mycarservices.json#checktirepressure - - name: check-oil-pressure - operation: mycarservices.json#checkoilpressure - - name: check-coolant-level - operation: mycarservices.json#checkcoolantlevel - - name: check-battery - operation: mycarservices.json#checkbattery -``` - - | -- -```yaml -id: vitalscheck -name: Car Vitals Check -version: '1.0.0' -specVersion: '0.8' -start: CheckVitals -states: - - name: CheckVitals - type: operation - actions: - - functionRef: Check Tire Pressure - - functionRef: Check Oil Pressure - - functionRef: Check Coolant Level - - functionRef: Check Battery - end: - produceEvents: - - eventRef: DisplayChecksOnDashboard - data: "${ .evaluations }" -functions: - - name: checkTirePressure - operation: mycarservices.json#checktirepressure - - name: checkOilPressure - operation: mycarservices.json#checkoilpressure - - name: checkCoolantLevel - operation: mycarservices.json#checkcoolantlevel - - name: checkBattery - operation: mycarservices.json#checkbattery -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "booklending", - "name": "booklending", - "description": "Book Lending Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "book-lending-request", - "states": [ - { - "name": "book-lending-request", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "book-lending-request-event" - ] - } - ], - "transition": "get-book-status" - }, - { - "name": "get-book-status", - "type": "operation", - "actions": [ - { - "name": "get-book-status", - "functionRef": { - "refName": "get-status-for-book", - "arguments": { - "bookid": "${ .book.id }" - } - } - } - ], - "transition": "book-status-decision" - }, - { - "name": "book-status-decision", - "type": "switch", - "dataConditions": [ - { - "name": "book-is-on-loan", - "condition": "${ .book.status == \"onloan\" }", - "transition": "report-status-to-lender" - }, - { - "name": "check-is-available", - "condition": "${ .book.status == \"available\" }", - "transition": "check-out-book" - } - ], - "defaultCondition": { - "end": true - } - }, - { - "name": "report-status-to-lender", - "type": "operation", - "actions": [ - { - "name": "report-status-to-lender", - "functionRef": { - "refName": "send-status-to-lender", - "arguments": { - "bookid": "${ .book.id }", - "message": "Book ${ .book.title } is already on loan" - } - } - } - ], - "transition": "wait-for-lender-response" - }, - { - "name": "wait-for-lender-response", - "type": "switch", - "eventConditions": [ - { - "name": "hold-book", - "eventRef": "hold-book-event", - "transition": "request-hold" - }, - { - "name": "decline-book-hold", - "eventRef": "decline-hold-event", - "transition": "cancel-request" - } - ], - "defaultCondition": { - "end": true - } - }, - { - "name": "request-hold", - "type": "operation", - "actions": [ - { - "name": "request-hold", - "functionRef": { - "refName": "request-hold-for-lender", - "arguments": { - "bookid": "${ .book.id }", - "lender": "${ .lender }" - } - } - } - ], - "transition": "sleep-two-weeks" - }, - { - "name": "cancel-request", - "type": "operation", - "actions": [ - { - "name": "cancel-request", - "functionRef": { - "refName": "cancel-hold-request-for-lender", - "arguments": { - "bookid": "${ .book.id }", - "lender": "${ .lender }" - } - } - } - ], - "transition": "sleep-two-weeks" - }, - { - "name": "sleep-two-weeks", - "type": "sleep", - "duration": "PT2W", - "transition": "get-book-status" - }, - { - "name": "check-out-book", - "type": "operation", - "actions": [ - { - "name": "check-out-book", - "functionRef": { - "refName": "check-out-book-with-id", - "arguments": { - "bookid": "${ .book.id }" - } - } - }, - { - "name": "notify-lender-for-checkout", - "functionRef": { - "refName": "notify-lender-for-checkout", - "arguments": { - "bookid": "${ .book.id }", - "lender": "${ .lender }" - } - } - } - ], - "end": true - } - ], - "functions": "file://books/lending/functions.json", - "events": "file://books/lending/events.json" -}``` - - | -- -```yaml -id: booklending -name: booklending -description: Book Lending Workflow -version: 1.0.0 -specVersion: "0.8" -start: book-lending-request -states: - - name: book-lending-request - type: event - onEvents: - - eventRefs: - - book-lending-request-event - transition: get-book-status - - name: get-book-status - type: operation - actions: - - name: get-book-status - functionRef: - refName: get-status-for-book - arguments: - bookid: ${ .book.id } - transition: book-status-decision - - name: book-status-decision - type: switch - dataConditions: - - name: book-is-on-loan - condition: ${ .book.status == "onloan" } - transition: report-status-to-lender - - name: check-is-available - condition: ${ .book.status == "available" } - transition: check-out-book - defaultCondition: - end: true - - name: report-status-to-lender - type: operation - actions: - - name: report-status-to-lender - functionRef: - refName: send-status-to-lender - arguments: - bookid: ${ .book.id } - message: Book ${ .book.title } is already on loan - transition: wait-for-lender-response - - name: wait-for-lender-response - type: switch - eventConditions: - - name: hold-book - eventRef: hold-book-event - transition: request-hold - - name: decline-book-hold - eventRef: decline-hold-event - transition: cancel-request - defaultCondition: - end: true - - name: request-hold - type: operation - actions: - - name: request-hold - functionRef: - refName: request-hold-for-lender - arguments: - bookid: ${ .book.id } - lender: ${ .lender } - transition: sleep-two-weeks - - name: cancel-request - type: operation - actions: - - name: cancel-request - functionRef: - refName: cancel-hold-request-for-lender - arguments: - bookid: ${ .book.id } - lender: ${ .lender } - transition: sleep-two-weeks - - name: sleep-two-weeks - type: sleep - duration: PT2W - transition: get-book-status - - name: check-out-book - type: operation - actions: - - name: check-out-book - functionRef: - refName: check-out-book-with-id - arguments: - bookid: ${ .book.id } - - name: notify-lender-for-checkout - functionRef: - refName: notify-lender-for-checkout - arguments: - bookid: ${ .book.id } - lender: ${ .lender } - end: true -functions: file://books/lending/functions.json -events: file://books/lending/events.json -``` - - | -
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "fillglassofwater", - "name": "fillglassofwater", - "description": "Fill glass of water workflow", - "version": "1.0.0", - "specVersion": "0.8", - "start": "check-if-full", - "functions": [ - { - "name": "increment-current-count-function", - "type": "expression", - "operation": ".counts.current += 1 | .counts.current" - } - ], - "states": [ - { - "name": "check-if-full", - "type": "switch", - "dataConditions": [ - { - "name": "need-to-fill-more", - "condition": "${ .counts.current < .counts.max }", - "transition": "add-water" - }, - { - "name": "glass-full", - "condition": ".counts.current >= .counts.max", - "end": true - } - ], - "defaultCondition": { - "end": true - } - }, - { - "name": "add-water", - "type": "operation", - "actions": [ - { - "name": "add-water", - "functionRef": "increment-current-count-function", - "actionDataFilter": { - "toStateData": ".counts.current" - } - } - ], - "transition": "check-if-full" - } - ] -}``` - - | -- -```yaml -id: fillglassofwater -name: fillglassofwater -description: Fill glass of water workflow -version: 1.0.0 -specVersion: "0.8" -start: check-if-full -functions: - - name: increment-current-count-function - type: expression - operation: .counts.current += 1 | .counts.current -states: - - name: check-if-full - type: switch - dataConditions: - - name: need-to-fill-more - condition: ${ .counts.current < .counts.max } - transition: add-water - - name: glass-full - condition: .counts.current >= .counts.max - end: true - defaultCondition: - end: true - - name: add-water - type: operation - actions: - - name: add-water - functionRef: increment-current-count-function - actionDataFilter: - toStateData: .counts.current - transition: check-if-full -``` - - | -
-
-
-
-
JSON | -YAML | -
---|---|
- -```json -{ - "id": "notifycustomerworkflow", - "name": "notifycustomerworkflow", - "description": "Notify Customer", - "version": "1.0.0", - "specVersion": "0.8", - "start": "wait-for-customer-event", - "states": [ - { - "name": "wait-for-customer-event", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "customer-event" - ], - "eventDataFilter": { - "data": "${ .customerId }", - "toStateData": "${ .eventCustomerId }" - }, - "actions": [ - { - "name": "notify-customer-function", - "functionRef": { - "refName": "notify-customer-function", - "arguments": { - "customerId": "${ .eventCustomerId }" - } - } - } - ] - } - ], - "stateDataFilter": { - "output": "${ .count = .count + 1 }" - }, - "transition": "check-event-quota" - }, - { - "name": "check-event-quota", - "type": "switch", - "dataConditions": [ - { - "name": "ready", - "condition": "${ try(.customerCount) != null and .customerCount > .quota.maxConsumedEvents }", - "end": { - "continueAs": { - "workflowId": "notifycustomerworkflow", - "version": "1.0.0", - "data": "${ del(.customerCount) }" - } - } - } - ], - "defaultCondition": { - "transition": "wait-for-customer-event" - } - } - ], - "events": [ - { - "name": "customer-event", - "type": "org.events.customerEvent", - "source": "customerSource" - } - ], - "functions": [ - { - "name": "notify-customer-function", - "operation": "http://myapis.org/customerapis.json#notifyCustomer" - } - ] -}``` - - | -- -```yaml -id: notifycustomerworkflow -name: notifycustomerworkflow -description: Notify Customer -version: 1.0.0 -specVersion: "0.8" -start: wait-for-customer-event -states: - - name: wait-for-customer-event - type: event - onEvents: - - eventRefs: - - customer-event - eventDataFilter: - data: ${ .customerId } - toStateData: ${ .eventCustomerId } - actions: - - name: notify-customer-function - functionRef: - refName: notify-customer-function - arguments: - customerId: ${ .eventCustomerId } - stateDataFilter: - output: ${ .count = .count + 1 } - transition: check-event-quota - - name: check-event-quota - type: switch - dataConditions: - - name: ready - condition: ${ try(.customerCount) != null and .customerCount > - .quota.maxConsumedEvents } - end: - continueAs: - workflowId: notifycustomerworkflow - version: 1.0.0 - data: ${ del(.customerCount) } - defaultCondition: - transition: wait-for-customer-event -events: - - name: customer-event - type: org.events.customerEvent - source: customerSource -functions: - - name: notify-customer-function - operation: http://myapis.org/customerapis.json#notifyCustomer -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "id": "customerbankingtransactions", - "name": "customerbankingtransactions", - "description": "Customer Banking Transactions Workflow", - "version": "1.0.0", - "specVersion": "0.8", - "autoRetries": true, - "constants": { - "largetxamount": 5000 - }, - "states": [ - { - "name": "process-transactions", - "type": "foreach", - "inputCollection": "${ .customer.transactions }", - "iterationParam": "${ .tx }", - "actions": [ - { - "name": "process-larger-transaction", - "functionRef": "banking-service-larger-tx", - "condition": "${ .tx >= $CONST.largetxamount }" - }, - { - "name": "process-smaller-transaction", - "functionRef": "banking-service-smaller-tx", - "condition": "${ .tx < $CONST.largetxamount }" - } - ], - "end": true - } - ], - "functions": [ - { - "name": "banking-service-larger-tx", - "type": "asyncapi", - "operation": "banking.yaml#largerTransation" - }, - { - "name": "banking-service-smaller-tx", - "type": "asyncapi", - "operation": "banking.yaml#smallerTransation" - } - ] -}``` - - | -- -```yaml -id: customerbankingtransactions -name: customerbankingtransactions -description: Customer Banking Transactions Workflow -version: 1.0.0 -specVersion: "0.8" -autoRetries: true -constants: - largetxamount: 5000 -states: - - name: process-transactions - type: foreach - inputCollection: ${ .customer.transactions } - iterationParam: ${ .tx } - actions: - - name: process-larger-transaction - functionRef: banking-service-larger-tx - condition: ${ .tx >= $CONST.largetxamount } - - name: process-smaller-transaction - functionRef: banking-service-smaller-tx - condition: ${ .tx < $CONST.largetxamount } - end: true -functions: - - name: banking-service-larger-tx - type: asyncapi - operation: banking.yaml#largerTransation - - name: banking-service-smaller-tx - type: asyncapi - operation: banking.yaml#smallerTransation -``` - - | -
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
JSON | -YAML | -|
---|---|---|
-
-```json
- |
-
-
-```yaml
- |
-- -```yaml -id: vitalscheck -name: Car Vitals Check -version: '1.0.0' -specVersion: '0.8' -start: CheckVitals -states: - - name: CheckVitals - type: operation - actions: - - functionRef: Check Tire Pressure - - functionRef: Check Oil Pressure - - functionRef: Check Coolant Level - - functionRef: Check Battery - end: - produceEvents: - - eventRef: DisplayChecksOnDashboard - data: "${ .evaluations }" -functions: - - name: checkTirePressure - operation: mycarservices.json#checktirepressure - - name: checkOilPressure - operation: mycarservices.json#checkoilpressure - - name: checkCoolantLevel - operation: mycarservices.json#checkcoolantlevel - - name: checkBattery - operation: mycarservices.json#checkbattery -``` - - | -
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
-
-
-
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
JSON | -YAML | -
---|---|
-
-```json
- |
-
-
-```yaml
- |
-
Workflow | -KPIs Extension | -
---|---|
- -```yaml -id: patientVitalsWorkflow -name: Monitor Patient Vitals -version: '1.0.0' -specVersion: '0.8' -start: MonitorVitals -extensions: - - extensionId: workflow-kpi-extension - path: file://myextensions/kpi.yml -events: - - name: HighBodyTemperature - type: org.monitor.highBodyTemp - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: HighBloodPressure - type: org.monitor.highBloodPressure - source: monitoringSource - correlation: - - contextAttributeName: patientId - - name: HighRespirationRate - type: org.monitor.highRespirationRate - source: monitoringSource - correlation: - - contextAttributeName: patientId -functions: - - name: callPulmonologist - operation: http://myapi.org/patientapi.json#callPulmonologist - - name: sendTylenolOrder - operation: http://myapi.org/patientapi.json#sendTylenol - - name: callNurse - operation: http://myapi.org/patientapi.json#callNurse -states: - - name: MonitorVitals - type: event - exclusive: true - onEvents: - - eventRefs: - - HighBodyTemperature - actions: - - functionRef: - refName: sendTylenolOrder - arguments: - patientid: "${ .patientId }" - - eventRefs: - - HighBloodPressure - actions: - - functionRef: - refName: callNurse - arguments: - patientid: "${ .patientId }" - - eventRefs: - - HighRespirationRate - actions: - - functionRef: - refName: callPulmonologist - arguments: - patientid: "${ .patientId }" - end: true -``` - - | -- -```yaml -extensionid: workflow-kpi-extension -currency: USD -workflow: - per: - time: PT1D - maxCost: '1300' - maxInvoked: '500' - minInvoked: '100' -events: -- for: HighBodyTemperature - per: - time: PT1D - avgConsumed: '50' -- for: HighBloodPressure - per: - time: PT1D - avgConsumed: '30' -functions: -- for: callPulmonologist - per: - instances: 1000 - maxCost: '400' - maxErrors: '5' - maxRetry: '10' - maxTimeout: '15' - avgInvoked: '40' -- for: sendTylenolOrder - per: - instances: 1000 - maxCost: '200' - maxErrors: '5' - maxRetry: '10' - maxTimeout: '15' - avgInvoked: '400' -states: -- for: MonitorVitals - per: - time: PT1D - maxCost: '300' - maxExec: '1000' - minExec: '50' -``` - - | -
Workflow | -Rate Limiting Extension | -
---|---|
- -```yaml -id: processapplication -name: Process Application -version: '1.0.0' -specVersion: '0.8' -extensions: - - extensionId: workflow-ratelimiting-extension - path: file://myextensions/ratelimiting.yml -start: ProcessNewApplication -states: - - name: ProcessNewApplication - type: event - onEvents: - - eventRefs: - - ApplicationReceivedEvent - actions: - - functionRef: processApplicationFunction - - functionRef: acceptApplicantFunction - - functionRef: depositFeesFunction - end: - produceEvents: - - eventRef: NotifyApplicantEvent -functions: - - name: processApplicationFunction - operation: file://myservice.json#process - - name: acceptApplicantFunction - operation: file://myservice.json#accept - - name: depositFeesFunction - operation: file://myservice.json#deposit -events: - - name: ApplicationReceivedEvent - type: application - source: "/applications/new" - - name: NotifyApplicantEvent - type: notifications - source: "/applicants/notify" -``` - - | -- -```yaml -extensionid: workflow-ratelimiting-extension -singleInstance: - maxActionsPerSecond: 0.1 - maxConcurrentActions: 200 - maxProducedEventsPerSecond: 2 - maxStates: '1000' - maxTransitions: '1000' -allInstances: - maxActionsPerSecond: 1 - maxConcurrentActions: 500 - maxProducedEventsPerSecond: 20 - maxStates: '10000' - maxTransitions: '10000' - -``` - - | -
-
-
-
-
-
-
-
-
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "stateDataFilter": { - "input": "${ .orders }", - "output": "${ .provisionedOrders }" - } -} -``` - - | -- -```yaml -stateDataFilter: - input: "${ .orders }" - output: "${ .provisionedOrders }" -``` - - | -
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "actionDataFilter": { - "fromStateData": "${ .language }", - "results": "${ .results.greeting }", - "toStateData": "${ .finalgreeting }" - } -} -``` - - | -- -```yaml -actionDataFilter: - fromStateData: "${ .language }" - results: "${ .results.greeting }" - toStateData: "${ .finalgreeting }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "eventDataFilter": { - "data": "${ .data.results }" - } -} -``` - - | -- -```yaml -eventDataFilter: - data: "${ .data.results }" -``` - - | -
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "sample-workflow", - "version": "1.0.0", - "specVersion": "0.8", - "description": "Sample Workflow", - "start": "MyStartingState", - "states": [], - "functions": [], - "events": [], - "errors": [], - "retries":[] -} -``` - - | -- -```yaml -name: sample-workflow -version: '1.0.0' -specVersion: '0.8' -description: Sample Workflow -start: MyStartingState -states: [] -functions: [] -events: [] -errors: [] -retries: [] -``` - - | -
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ -"name": "monitor-vitals", -"type": "event", -"exclusive": true, -"onEvents": [{ - "eventRefs": ["high-body-temperature"], - "actions": [{ - "functionRef": { - "refName": "send-tylenol-order", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] - }, - { - "eventRefs": ["high-blood-pressure"], - "actions": [{ - "functionRef": { - "refName": "call-nurse", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] - }, - { - "eventRefs": ["high-respiration-rate"], - "actions": [{ - "functionRef": { - "refName": "call-pulmonologist", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] - } -], -"end": { - "terminate": true -} -} -``` - - | -- -```yaml -name: monitor-vitals -type: event -exclusive: true -onEvents: -- eventRefs: - - high-body-temperature - actions: - - functionRef: - refName: send-tylenol-order - arguments: - patientid: "${ .patientId }" -- eventRefs: - - high-blood-pressure - actions: - - functionRef: - refName: call-nurse - arguments: - patientid: "${ .patientId }" -- eventRefs: - - high-respiration-rate - actions: - - functionRef: - refName: call-pulmonologist - arguments: - patientid: "${ .patientId }" -end: - terminate: true -``` - - | -
-
-
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "reject-application", - "type": "operation", - "actionMode": "sequential", - "actions": [ - { - "functionRef": { - "refName": "send-rejection-email-function", - "arguments": { - "customer": "${ .customer }" - } - } - } - ], - "end": true -} -``` - - | -- -```yaml -name: reject-application -type: operation -actionMode: sequential -actions: -- functionRef: - refName: send-rejection-email-function - arguments: - customer: "${ .customer }" -end: true -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name":"check-visa-status", - "type":"switch", - "eventConditions": [ - { - "eventRef": "visa-approved-event", - "transition": "handle-approved-visa" - }, - { - "eventRef": "visa-rejected-event", - "transition": "handle-rejected-visa" - } - ], - "timeouts": { - "eventTimeout": "PT1H" - }, - "defaultCondition": { - "transition": "handle-no-visa-decision" - } -} -``` - - | -- -```yaml -name: check-visa-status -type: switch -eventConditions: -- eventRef: visa-approved-event - transition: handle-approved-visa -- eventRef: visa-rejected-event - transition: handle-rejected-visa -timeouts: - eventTimeout: PT1H -defaultCondition: - transition: handle-no-visa-decision -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json - { - "name":"parallel-exec", - "type":"parallel", - "completionType": "allOf", - "branches": [ - { - "name": "branch-1", - "actions": [ - { - "functionRef": { - "refName": "function-name-one", - "arguments": { - "order": "${ .someParam }" - } - } - } - ] - }, - { - "name": "branch-2", - "actions": [ - { - "functionRef": { - "refName": "function-name-two", - "arguments": { - "order": "${ .someParam }" - } - } - } - ] - } - ], - "end": true -} -``` - - | -- -```yaml -name: parallel-exec -type: parallel -completionType: allOf -branches: -- name: branch-1 - actions: - - functionRef: - refName: function-name-one - arguments: - order: "${ .someParam }" -- name: branch-2 - actions: - - functionRef: - refName: function-name-two - arguments: - order: "${ .someParam }" -end: true -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name":"hello", - "type":"inject", - "data": { - "result": "Hello" - }, - "transition": "world" -} -``` - - | -- -```yaml -name: hello -type: inject -data: - result: Hello -transition: world -``` - - | -
JSON | -YAML | -
---|---|
- - ```json - { - "name":"simple-inject-state", - "type":"inject", - "data": { - "person": { - "fname": "John", - "lname": "Doe", - "address": "1234 SomeStreet", - "age": 40 - } - }, - "transition": "greet-person-state" - } - ``` - - | -- -```yaml - name: simple-inject-state - type: inject - data: - person: - fname: John - lname: Doe - address: 1234 SomeStreet - age: 40 - transition: greet-person-state -``` - - | -
JSON | -YAML | -
---|---|
- -```json - { - "name":"simple-inject-state", - "type":"inject", - "data": { - "people": [ - { - "fname": "John", - "lname": "Doe", - "address": "1234 SomeStreet", - "age": 40 - }, - { - "fname": "Marry", - "lname": "Allice", - "address": "1234 SomeStreet", - "age": 25 - }, - { - "fname": "Kelly", - "lname": "Mill", - "address": "1234 SomeStreet", - "age": 30 - } - ] - }, - "stateDataFilter": { - "output": "${ {people: [.people[] | select(.age < 40)]} }" - }, - "transition": "greet-person-state" - } -``` - - | -- -```yaml - name: simple-inject-state - type: inject - data: - people: - - fname: John - lname: Doe - address: 1234 SomeStreet - age: 40 - - fname: Marry - lname: Allice - address: 1234 SomeStreet - age: 25 - - fname: Kelly - lname: Mill - address: 1234 SomeStreet - age: 30 - stateDataFilter: - output: "${ {people: [.people[] | select(.age < 40)]} }" - transition: greet-person-state -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "provision-orders-state", - "type": "foreach", - "inputCollection": "${ .orders }", - "iterationParam": "singleorder", - "outputCollection": "${ .provisionresults }", - "actions": [ - { - "functionRef": { - "refName": "provision-order-function", - "arguments": { - "order": "${ $singleorder }" - } - } - } - ] -} -``` - - | -- -```yaml -name: provision-orders-state -type: foreach -inputCollection: "${ .orders }" -iterationParam: "singleorder" -outputCollection: "${ .provisionresults }" -actions: -- functionRef: - refName: provision-order-function - arguments: - order: "${ $singleorder }" -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "send-confirmation-for-completed-orders", - "version": "1.0.0", - "specVersion": "0.8", - "start": "send-confirm-state", - "functions": [ - { - "name": "send-confirmation-function", - "operation": "file://confirmationapi.json#sendOrderConfirmation" - } - ], - "states": [ - { - "name":"send-confirm-state", - "type":"foreach", - "inputCollection": "${ [.orders[] | select(.completed == true)] }", - "iterationParam": "completedorder", - "outputCollection": "${ .confirmationresults }", - "actions":[ - { - "functionRef": { - "refName": "send-confirmation-function", - "arguments": { - "orderNumber": "${ $completedorder.orderNumber }", - "email": "${ $completedorder.email }" - } - } - }], - "end": true - }] -} -``` - - | -- -```yaml -name: send-confirmation-for-completed-orders -version: '1.0.0' -specVersion: '0.8' -start: send-confirm-state -functions: -- name: send-confirmation-function - operation: file://confirmationapi.json#sendOrderConfirmation -states: -- name: send-confirm-state - type: foreach - inputCollection: "${ [.orders[] | select(.completed == true)] }" - iterationParam: completedorder - outputCollection: "${ .confirmationresults }" - actions: - - functionRef: - refName: send-confirmation-function - arguments: - orderNumber: "${ $completedorder.orderNumber }" - email: "${ $completedorder.email }" - end: true -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "check-credit", - "type": "callback", - "action": { - "functionRef": { - "refName": "call-credit-check-microservice", - "arguments": { - "customer": "${ .customer }" - } - } - }, - "eventRef": "credit-check-completed-event", - "timeouts": { - "stateExecTimeout": "PT15M" - }, - "transition": "evaluate-decision" -} -``` - - | -- -```yaml -name: check-credit -type: callback -action: - functionRef: - refName: call-credit-check-microservice - arguments: - customer: "${ .customer }" -eventRef: credit-check-completed-event -timeouts: - stateExecTimeout: PT15M -transition: evaluate-decision -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "hello-world-function", - "operation": "https://hellworldservice.api.com/api.json#helloWorld" -} -``` - - | -- -```yaml -name: hello-world-function -operation: https://hellworldservice.api.com/api.json#helloWorld -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "applicant-info", - "type": "org.application.info", - "source": "applicationssource", - "correlation": [ - { - "contextAttributeName": "applicantId" - } - ] -} -``` - - | -- -```yaml -name: applicant-info -type: org.application.info -source: applicationssource -correlation: -- contextAttributeName: applicantId -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "correlation": [ - { - "contextAttributeName": "patientId" - }, - { - "contextAttributeName": "department", - "contextAttributeValue" : "UrgentCare" - } - ] -} -``` - - | -- -```yaml -correlation: -- contextAttributeName: patientId -- contextAttributeName: department - contextAttributeValue: UrgentCare -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "eventRefs": ["high-body-temperature"], - "actions": [{ - "functionRef": { - "refName": "send-tylenol-order", - "arguments": { - "patientid": "${ .patientId }" - } - } - }] -} -``` - - | -- -```yaml -eventRefs: -- high-body-temperature -actions: -- functionRef: - refName: send-tylenol-order - arguments: - patientid: "${ .patientId }" -``` - - | -
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "finalize-application-action", - "functionRef": { - "refName": "finalize-application-function", - "arguments": { - "applicantid": "${ .applicantId }" - } - } -} -``` - - | -- -```yaml -name: finalize-application-action -functionRef: - refName: finalize-application-function - arguments: - applicantid: "${ .applicantId }" -``` - - | -
-
-
- -
JSON | -YAML | -
---|---|
- -```json -{ - "refName": "finalize-application-function", - "arguments": { - "applicantid": "${ .applicantId }" - } -} -``` - - | -- -```yaml -refName: finalize-application-function -arguments: - applicantid: "${ .applicantId }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "publish": { - "event": "make-vet-appointment", - "data": "${ .patientInfo }", - } -} -``` - - | -- -```yaml -publish: - event: make-vet-appointment - data: "${ .patientInfo }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "subscribe": { - "name": "approved-appointment", - } -} -``` - - | -- -```yaml -eventRef: - subscribe: approved-appointment - -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "workflowId": "handle-approved-visa", - "version": "2.0.0" -} -``` - - | -- -```yaml -workflowId: handle-approved-visa -version: '2.0.0' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "retries": [ - { - "name": "retry-five-times", - "maxAttempts": 5 - } - ], - "errors": { - "definitions": [ - { - "name": "service-not-available-error", - "type": "https://serverlessworkflow.io/spec/errors/communication", - "status": 503, - "title": "Service Not Available", - "detail": "Failed to contact service, even after multiple retries" - } - ], - "handlers": [ - { - "name": "handle-503", - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times", - "then": { - "throw": { - "refName": "service-not-available-error" - } - } - } - ], - "policies": [ - { - "name": "fault-tolerance-policy", - "handlers": [ - { - "refName": "handle-503" - } - ] - } - ] - } -} -``` - - | -- -```yaml -retries: - - name: retry-five-times - maxAttempts: 5 -errors: - definitions: - - name: service-not-available-error - type: https://serverlessworkflow.io/spec/errors/communication - status: 503 - title: Service Not Available - detail: Failed to contact service, even after multiple retries - handlers: - - name: handle-503 - when: - - status: 503 - retry: retry-five-times - then: - throw: - refName: service-not-available-error - policies: - - name: fault-tolerance-policy - handlers: - - refName: handle-503 -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "instance": "/states/0/actions/0", - "type": "https://example.com/errors#timeout", - "status": 504, - "title": "Function Timeout", - "detail": "The function 'my-function' timed out." -} -``` - - | -- -```yaml -instance: "/states/0/actions/0" -type: "https://example.com/errors#timeout" -status: 504 -title: "Function Timeout" -detail: "The function 'my-function' timed out." -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "type": "https://example.com/errors#timeout", - "status": 504 -} -``` - - | -- -```yaml -type: "https://example.com/errors#timeout" -status: 504 -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "handlers": [ - { - "name": "handle-invalid-error", - "when": [ - { "error": "invalid" }, - { "status": 404 }, - { "status": 403 } - ], - "then": { - "transition": "my-state" - } - }, - { - "name": "handle-timeout-error", - "when": [ - { "status": 503 } - ], - "retry": "my-retry-policy", - "then": { - "transition": "my-state" - } - } - ] - } -} -``` - - | -- -```yaml -errors: - handlers: - - name: 'handle-invalid-error' - when: - - type: 'invalid' - - status: 404 - - status: 403 - then: - transition: 'my-state' - - name: 'handle-timeout-error' - when: - - status: 503 - retry: 'my-retry-policy' - then: - transition: 'my-state' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "policies": [ - { - "name": "my-retry-policy", - "handlers": [ - { - "refName": "handle-timeout-error" - }, - { - "when": [ - { "status": 503 } - ], - "retry": "my-retry-policy" - } - ] - } - ] - } -} -``` - - | -- -```yaml -errors: - policies: - - name: 'my-retry-policy' - handlers: - - refName: 'handle-timeout-error' - - when: - - status: 503 - retry: 'my-retry-policy' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "policies": [ - { - "name": "my-retry-policy", - "handlers": [ - { - "refName": "handle-timeout-error" - }, - { - "when": [ - { "status": 503 } - ], - "retry": "my-retry-policy" - } - ] - } - ] - } -} -``` - - | -- -```yaml -errors: - policies: - - name: 'my-retry-policy' - handlers: - - refName: 'handle-timeout-error' - - when: - - status: 503 - retry: 'my-retry-policy' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "when": [ - { - "status": 503 - } - ], - "then": { - "transition": "my-state" - } -} -``` - - | -- -```yaml -when: - - status: 503 -then: - transition: 'my-state' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "throw": { - "type": "https://serverlessworkflow.io/spec/errors/runtime", - "status": 400, - "detail": "${ $CONST.localizedErrorDetail }" - } -} -``` - - | -- -```yaml -throw: - type: https://serverlessworkflow.io/spec/errors/runtime - status: 400 - detail: ${ $CONST.localizedErrorDetail } -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "timeout-retry-strat", - "delay": "PT2M", - "maxAttempts": 3, - "jitter": "PT0.001S" -} -``` - - | -- -```yaml -name: timeout-retry-strat -delay: PT2M -maxAttempts: 3 -jitter: PT0.001S -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "produceEvents": [{ - "eventRef": "produce-result-event", - "data": "${ .result.data }" - }], - "nextState": "eval-result-state" -} -``` - - | -- -```yaml -produceEvents: -- eventRef: produce-result-event - data: "${ .result.data }" -nextState: eval-result-state -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "eighteen-or-older", - "condition": "${ .applicant | .age >= 18 }", - "transition": "start-application" -} -``` - - | -- -```yaml -name: eighteen-or-older -condition: "${ .applicant | .age >= 18 }" -transition: start-application -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "visa-approved", - "eventRef": "visa-approved-event", - "transition": "handle-approved-visa" -} -``` - - | -- -```yaml -name: visa-approved -eventRef: visa-approved-event -transition: handle-approved-visa -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "name": "branch-1", - "actions": [ - { - "functionRef": { - "refName": "function-name-one", - "arguments": { - "order": "${ .someParam }" - } - } - }, - { - "functionRef": { - "refName": "function-name-two", - "arguments": { - "order": "${ .someParamTwo }" - } - } - } - ] -} -``` - - | -- -```yaml -name: branch-1 -actions: -- functionRef: - refName: function-name-one - arguments: - order: "${ .someParam }" -- functionRef: - refName: function-name-two - arguments: - order: "${ .someParamTwo }" -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "stateName": "my-starting-state", - "schedule": "2020-03-20T09:00:00Z/PT2H" -} -``` - - | -- -```yaml -stateName: my-starting-state -schedule: 2020-03-20T09:00:00Z/PT2H -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "cron": "0 0/15 * * * ?" -} -``` - - | -- -```yaml -cron: 0 0/15 * * * ? -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "expression": "0 15,30,45 * ? * *", - "validUntil": "2021-11-05T08:15:30-05:00" -} -``` - - | -- -```yaml -expression: 0 15,30,45 * ? * * -validUntil: '2021-11-05T08:15:30-05:00' -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "terminate": true, - "produceEvents": [{ - "eventRef": "provisioning-complete-event", - "data": "${ .provisionedOrders }" - }] -} -``` - - | -- -```yaml -terminate: true -produceEvents: -- eventRef: provisioning-complete-event - data: "${ .provisionedOrders }" - -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "eventRef": "provisioning-complete-event", - "data": "${ .provisionedOrders }", - "contextAttributes": { - "buyerId": "${ .buyerId }" - } - } -``` - - | -- -```yaml -eventRef: provisioning-complete-event -data: "${ .provisionedOrders }" -contextAttributes: - buyerId: "${ .buyerId }" -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "actions": [ - { - "name": "my-action", - "functionRef": "my-function", - "onErrors": [ - { - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times" - } - ] - } - ] -} - -``` - - | -- -```yaml -actions: - - name: my-action - functionRef: my-function - onErrors: - - when: - - status: 503 - retry: retry-five-times -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "definitions": [ - { - "name": "service-not-available-error", - "type": "https://serverlessworkflow.io/spec/errors/communication", - "status": 503, - "title": "Service Not Available", - "detail": "Failed to contact service, even after multiple retries" - } - ], - "handlers": [ - { - "name": "handle-503", - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times", - "then": { - "throw": { - "refName": "service-not-available-error" - } - } - } - ] - }, - "states": [ - { - "name": "my-state", - "type": "operation", - "actions": [ - { - "name": "my-action", - "functionRef": "my-function", - "onErrors": [ - { - "refName": "handle-503" - } - ] - } - ] - } - ] -} - -``` - - | -- -```yaml -errors: - definitions: - - name: service-not-available-error - type: https://serverlessworkflow.io/spec/errors/communication - status: 503 - title: Service Not Available - detail: Failed to contact service, even after multiple retries - handlers: - - name: handle-503 - when: - - status: 503 - retry: retry-five-times - then: - throw: - refName: service-not-available-error -states: - - name: my-state - type: operation - actions: - - name: my-action - functionRef: my-function - onErrors: - - refName: handle-503 -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "errors": { - "definitions": [ - { - "name": "service-not-available-error", - "type": "https://serverlessworkflow.io/spec/errors/communication", - "status": 503, - "title": "Service Not Available", - "detail": "Failed to contact service, even after multiple retries" - } - ], - "handlers": [ - { - "name": "handle-503", - "when": [ - { - "status": 503 - } - ], - "retry": "retry-five-times", - "then": { - "throw": { - "refName": "service-not-available-error" - } - } - } - ] - }, - "states": [ - { - "name": "my-state", - "type": "operation", - "actions": [ - { - "name": "my-action", - "functionRef": "my-function", - "onErrors": [ - { - "refName": "handle-503" - } - ] - } - ] - } - ] -} - -``` - - | -- -```yaml -errors: - definitions: - - name: service-not-available-error - type: https://serverlessworkflow.io/spec/errors/communication - status: 503 - title: Service Not Available - detail: Failed to contact service, even after multiple retries - handlers: - - name: handle-503 - when: - - status: 503 - retry: retry-five-times - then: - throw: - refName: service-not-available-error - policy: - - name: fault-tolerance - handlers: - - refName: handle-503 -states: - - name: my-state - type: operation - actions: - - name: my-action - functionRef: my-function - onErrors: fault-tolerance -``` - - | -
- -
JSON | -YAML | -
---|---|
- -```json -{ - "duration": "PT2M", - "runBefore": "createandsendreport" -} -``` - - | -- -```yaml -duration: PT2M -runBefore: createandsendreport -``` - - | -
JSON | -YAML | -
---|---|
- -```json - { - "states": [ - { - "name": "new-item-purchase", - "type": "event", - "onEvents": [ - { - "eventRefs": [ - "new-purchase" - ], - "actions": [ - { - "functionRef": { - "refName": "debit-customer-function", - "arguments": { - "customerid": "${ .purchase.customerid }", - "amount": "${ .purchase.amount }" - } - } - }, - { - "functionRef": { - "refName": "send-purchase-confirmation-email-function", - "arguments": { - "customerid": "${ .purchase.customerid }" - } - } - } - ] - } - ], - "compensatedBy": "cancel-purchase", - "transition": "some-next-workflow-state" - }, - { - "name": "cancel-purchase", - "type": "operation", - "usedForCompensation": true, - "actions": [ - { - "functionRef": { - "refName": "credit-customer-function", - "arguments": { - "customerid": "${ .purchase.customerid }", - "amount": "${ .purchase.amount }" - } - } - }, - { - "functionRef": { - "refName": "send-purchase-cancellation-email-function", - "arguments": { - "customerid": "${ .purchase.customerid }" - } - } - } - ] - } - ] - } -``` - - | -- -```yaml -states: -- name: new-item-purchase - type: event - onEvents: - - eventRefs: - - new-purchase - actions: - - functionRef: - refName: debit-customer-function - arguments: - customerid: "${ .purchase.customerid }" - amount: "${ .purchase.amount }" - - functionRef: - refName: send-purchase-confirmation-email-function - arguments: - customerid: "${ .purchase.customerid }" - compensatedBy: cancel-purchase - transition: some-next-workflow-state -- name: CancelPurchase - type: operation - usedForCompensation: true - actions: - - functionRef: - refName: credit-customer-function - arguments: - customerid: "${ .purchase.customerid }" - amount: "${ .purchase.amount }" - - functionRef: - refName: send-purchase-cancellation-email-function - arguments: - customerid: "${ .purchase.customerid }" -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "transition": { - "compensate": true, - "nextState": "next-workflow-state" - } -} -``` - - | -- -```yaml -transition: - compensate: true - nextState: next-workflow-state -``` - - | -
JSON | -YAML | -
---|---|
- -```json -{ - "end": { - "compensate": true - } -} -``` - - | -- -```yaml -end: - compensate: true -``` - - | -
-
-
-
-