Skip to content

Commit 508fbef

Browse files
Merge branch 'main' into schema-validation-order
2 parents e80775d + 7539516 commit 508fbef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1642
-103
lines changed

.github/workflows/schema-check.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ on:
2929
- 'examples/**'
3030
pull_request:
3131
branches: [ "main" ]
32-
paths:
33-
- 'schema/**'
34-
- 'examples/**'
35-
3632
jobs:
3733
build:
3834
defaults:

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,11 @@ It is a member project of the [CNCF Serverless Working Group](https://github.com
109109
## Documentation
110110

111111
The documentation for Serverless Workflow includes:
112+
112113
- [**DSL**](dsl.md): Documents the fundamentals aspects and concepts of the Serverless Workflow DSL
113114
- [**DSL Reference**](dsl-reference.md): References all the definitions used by the Serverless Workflow DSL
115+
- [**Examples**](./examples/README.md): A collection of practical examples demonstrating specific features and functionalities of Serverless Workflow.
116+
- [**Use Cases**](./use-cases/README.md): Detailed use cases illustrating how Serverless Workflow can be applied in various real-world scenarios.
114117

115118
## Community
116119

ctk/features/call.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Feature: Call Task
104104
with:
105105
document:
106106
endpoint: "https://petstore.swagger.io/v2/swagger.json"
107-
operation: findPetsByStatus
107+
operationId: findPetsByStatus
108108
parameters:
109109
status: ${ .status }
110110
output:
@@ -132,7 +132,7 @@ Feature: Call Task
132132
with:
133133
document:
134134
endpoint: "https://petstore.swagger.io/v2/swagger.json"
135-
operation: getPetById
135+
operationId: getPetById
136136
parameters:
137137
petId: ${ .petId }
138138
output: response

ctk/features/raise.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ Feature: Raise Task
2424
status: 400
2525
type: https://serverlessworkflow.io/errors/types/compliance
2626
title: Compliance Error
27-
instance: /do/raiseComplianceError
27+
instance: /do/0/raiseError
2828
"""

ctk/features/try.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Feature: Try Task
4343
And the workflow output should have properties 'error', 'error.type', 'error.status', 'error.title'
4444
And the workflow output should have a 'error.instance' property with value:
4545
"""yaml
46-
/do/tryGetPet/try
46+
/do/0/tryGetPet/try/0/getPet
4747
"""
4848

4949
# Tests that try tasks fault when an uncaught error is raised

dsl-reference.md

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
- [Certificate](#certificate-authentication)
3838
- [Digest](#digest-authentication)
3939
- [OAUTH2](#oauth2-authentication)
40+
- [OpenIdConnect](#openidconnect-authentication)
4041
+ [Extension](#extension)
4142
+ [Error](#error)
4243
- [Standard Error Types](#standard-error-types)
@@ -148,7 +149,7 @@ use:
148149
petStoreOAuth2:
149150
oauth2:
150151
authority: https://petstore.swagger.io/.well-known/openid-configuration
151-
grant: client-credentials
152+
grant: client_credentials
152153
client:
153154
id: workflow-runtime
154155
secret: "**********"
@@ -1111,6 +1112,7 @@ Defines the mechanism used to authenticate users and workflows attempting to acc
11111112
| certificate | [`certificateAuthentication`](#certificate-authentication) | `no` | The `certificate` authentication scheme to use, if any.<br>Required if no other property has been set, otherwise ignored. |
11121113
| digest | [`digestAuthentication`](#digest-authentication) | `no` | The `digest` authentication scheme to use, if any.<br>Required if no other property has been set, otherwise ignored. |
11131114
| oauth2 | [`oauth2`](#oauth2-authentication) | `no` | The `oauth2` authentication scheme to use, if any.<br>Required if no other property has been set, otherwise ignored. |
1115+
| oidc | [`oidc`](#openidconnect-authentication) | `no` | The `oidc` authentication scheme to use, if any.<br>Required if no other property has been set, otherwise ignored. |
11141116

11151117
##### Examples
11161118

@@ -1209,19 +1211,59 @@ do:
12091211

12101212
#### Digest Authentication
12111213

1214+
Defines the fundamentals of a 'digest' authentication.
1215+
1216+
##### Properties
1217+
1218+
| Property | Type | Required | Description |
1219+
|----------|:----:|:--------:|-------------|
1220+
| username | `string` | `yes` | The username to use. |
1221+
| password | `string` | `yes` | The password to use. |
1222+
1223+
##### Examples
1224+
1225+
```yaml
1226+
document:
1227+
dsl: '1.0.0-alpha1'
1228+
namespace: test
1229+
name: digest-authentication-example
1230+
version: '0.1.0'
1231+
use:
1232+
authentications:
1233+
sampleDigest:
1234+
digest:
1235+
username: admin
1236+
password: password123
1237+
do:
1238+
- sampleTask:
1239+
call: http
1240+
with:
1241+
method: get
1242+
endpoint:
1243+
uri: https://secured.fake.com/sample
1244+
authentication:
1245+
use: sampleDigest
1246+
```
12121247

12131248
#### OAUTH2 Authentication
12141249

1215-
Defines the fundamentals of an 'oauth2' authentication
1250+
Defines the fundamentals of an 'oauth2' authentication.
12161251

12171252
##### Properties
12181253

1219-
| Property | Type | Required | Description |
1220-
|----------|:----:|:--------:|-------------|
1221-
| authority | [`uri-template`](#uri-template) | `yes` | The URI that references the OAuth2 authority to use. |
1222-
| grant | `string` | `yes` | The grant type to use. |
1223-
| client.id | `string` | `yes` | The client id to use. |
1254+
| Name | Type | Required | Description |
1255+
|:-----|:----:|:--------:|:------------|
1256+
| authority | `uri-template` | `yes` | The URI that references the authority to use when making OAuth2 calls. |
1257+
| endpoints.token | `uri-template` | `no` | The relative path to the endpoint for OAuth2 token requests.<br>Defaults to `/oauth2/token`. |
1258+
| endpoints.revocation | `uri-template` | `no` | The relative path to the endpoint used to invalidate tokens.<br>Defaults to `/oauth2/revoke`. |
1259+
| endpoints.introspection | `uri-template` | `no` | The relative path to the endpoint used to validate and obtain information about a token, typically to check its validity and associated metadata.<br>Defaults to `/oauth2/introspect`. |
1260+
| grant | `string` | `yes` | The grant type to use.<br>Supported values are `authorization_code`, `client_credentials`, `password`, `refresh_token` and `urn:ietf:params:oauth:grant-type:token-exchange`. |
1261+
| client.id | `string` | `no` | The client id to use.<br>Required if the `client.authentication` method has **not** been set to `none`. |
12241262
| client.secret | `string` | `no` | The client secret to use, if any. |
1263+
| client.assertion | `string` | `no` | A JWT containing a signed assertion with your application credentials.<br>Required when `client.authentication` has been set to `private_key_jwt`. |
1264+
| client.authentication | `string` | `no` | The client authentication method to use.<br>Supported values are `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt` or `none`.<br>Defaults to `client_secret_post`. |
1265+
| request.encoding | `string` | `no` | The encoding of the token request.<br>Supported values are `application/x-www-form-urlencoded` and `application/json`.<br>Defaults to application/x-www-form-urlencoded. |
1266+
| issuers | `uri-template[]` | `no` | A list that contains that contains valid issuers that will be used to check against the issuer of generated tokens. |
12251267
| scopes | `string[]` | `no` | The scopes, if any, to request the token for. |
12261268
| audiences | `string[]` | `no` | The audiences, if any, to request the token for. |
12271269
| username | `string` | `no` | The username to use. Used only if the grant type is `Password`. |
@@ -1246,8 +1288,10 @@ do:
12461288
uri: https://secured.fake.com/sample
12471289
authentication:
12481290
oauth2:
1249-
authority: http://keycloak/realms/fake-authority/.well-known/openid-configuration
1250-
grant: client-credentials
1291+
authority: http://keycloak/realms/fake-authority
1292+
endpoints:
1293+
token: /oauth2/token
1294+
grant: client_credentials
12511295
client:
12521296
id: workflow-runtime
12531297
secret: "**********"
@@ -1266,6 +1310,55 @@ Represents the definition of an OAUTH2 token
12661310
| token | `string` | `yes` | The security token to use to use. |
12671311
| type | `string` | `yes` | The type of security token to use. |
12681312

1313+
#### OpenIdConnect Authentication
1314+
1315+
Defines the fundamentals of an 'oidc' authentication.
1316+
1317+
##### Properties
1318+
1319+
| Name | Type | Required | Description |
1320+
|:-----|:----:|:--------:|:------------|
1321+
| authority | `uri-template` | `yes` | The URI that references the authority to use when making OpenIdConnect calls. |
1322+
| grant | `string` | `yes` | The grant type to use.<br>Supported values are `authorization_code`, `client_credentials`, `password`, `refresh_token` and `urn:ietf:params:oauth:grant-type:token-exchange`. |
1323+
| client.id | `string` | `no` | The client id to use.<br>Required if the `client.authentication` method has **not** been set to `none`. |
1324+
| client.secret | `string` | `no` | The client secret to use, if any. |
1325+
| client.assertion | `string` | `no` | A JWT containing a signed assertion with your application credentials.<br>Required when `client.authentication` has been set to `private_key_jwt`. |
1326+
| client.authentication | `string` | `no` | The client authentication method to use.<br>Supported values are `client_secret_basic`, `client_secret_post`, `client_secret_jwt`, `private_key_jwt` or `none`.<br>Defaults to `client_secret_post`. |
1327+
| request.encoding | `string` | `no` | The encoding of the token request.<br>Supported values are `application/x-www-form-urlencoded` and `application/json`.<br>Defaults to application/x-www-form-urlencoded. |
1328+
| issuers | `uri-template[]` | `no` | A list that contains that contains valid issuers that will be used to check against the issuer of generated tokens. |
1329+
| scopes | `string[]` | `no` | The scopes, if any, to request the token for. |
1330+
| audiences | `string[]` | `no` | The audiences, if any, to request the token for. |
1331+
| username | `string` | `no` | The username to use. Used only if the grant type is `Password`. |
1332+
| password | `string` | `no` | The password to use. Used only if the grant type is `Password`. |
1333+
| subject | [`oauth2Token`](#oauth2-token) | `no` | The security token that represents the identity of the party on behalf of whom the request is being made. |
1334+
| actor | [`oauth2Token`](#oauth2-token) | `no` | The security token that represents the identity of the acting party. |
1335+
1336+
##### Examples
1337+
1338+
```yaml
1339+
document:
1340+
dsl: '1.0.0-alpha1'
1341+
namespace: test
1342+
name: oidc-authentication-example
1343+
version: '0.1.0'
1344+
do:
1345+
- sampleTask:
1346+
call: http
1347+
with:
1348+
method: get
1349+
endpoint:
1350+
uri: https://secured.fake.com/sample
1351+
authentication:
1352+
oidc:
1353+
authority: http://keycloak/realms/fake-authority/.well-known/openid-configuration
1354+
grant: client_credentials
1355+
client:
1356+
id: workflow-runtime
1357+
secret: "**********"
1358+
scopes: [ api ]
1359+
audiences: [ runtime ]
1360+
```
1361+
12691362
### Extension
12701363

12711364
Holds the definition for extending functionality, providing configuration options for how an extension extends and interacts with other components.
@@ -1358,7 +1451,7 @@ Defines the [Problem Details RFC](https://datatracker.ietf.org/doc/html/rfc7807)
13581451
|----------|:----:|:--------:|-------------|
13591452
| type | [`uri-template`](#uri-template) | `yes` | A URI reference that identifies the [`error`](#error) type. <br><u>For cross-compatibility concerns, it is strongly recommended to use [Standard Error Types](#standard-error-types) whenever possible.<u><br><u>Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error).<u> |
13601453
| status | `integer` | `yes` | The status code generated by the origin for this occurrence of the [`error`](#error).<br><u>For cross-compatibility concerns, it is strongly recommended to use [HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231#section-6) whenever possible.<u><br><u>Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error).<u> |
1361-
| instance | `string` | `yes` | A [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) used to reference the component the [`error`](#error) originates from.<br><u>Runtimes **MUST** set the property when raising or escalating the [`error`](#error). Otherwise ignore.<u> |
1454+
| instance | `string` | `no` | A [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) used to reference the component the [`error`](#error) originates from.<br><u>Runtimes **MUST** set the property when raising or escalating the [`error`](#error). Otherwise ignore.<u> |
13621455
| title | `string` | `no` | A short, human-readable summary of the [`error`](#error). |
13631456
| detail | `string` | `no` | A human-readable explanation specific to this occurrence of the [`error`](#error). |
13641457

dsl.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- [Components](#components)
1313
+ [Task](#task)
1414
- [Scheduling](#scheduling)
15+
+ [Event-Driven Scheduling](#event-driven-scheduling)
1516
+ [Task Flow](#task-flow)
1617
+ [Data Flow](#data-flow)
1718
+ [Runtime Expressions](#runtime-expressions)
@@ -150,6 +151,24 @@ Workflow scheduling in ServerlessWorkflow allows developers to specify when and
150151

151152
See the [DSL reference](dsl-reference.md#schedule) for more details about workflow scheduling.
152153

154+
##### Event-driven scheduling
155+
156+
###### Input of event-driven scheduled workflows
157+
158+
In event-driven scheduled workflows, the input is structured as an array containing the events that trigger the execution of the workflow. This array serves as a vital resource, providing workflow authors access to all relevant data associated with each triggering event. When an event activates the workflow, it populates this array with one or more occurrences, allowing authors to process multiple events simultaneously as needed.
159+
160+
Authors can reference individual events within the array using syntax such as $workflow.input[index], where index indicates the event's position, starting from 0. For instance, $workflow.input[0] refers to the first event, while $workflow.input[1] refers to the second. This structure allows for easy access to specific event details, and if multiple events are received at once, authors can iterate through the array to handle each one appropriately. This flexibility ensures that workflows can respond effectively to various conditions and triggers, enhancing their overall responsiveness and functionality.
161+
162+
###### Distinguishing event-driven scheduling from start `listen` Tasks
163+
164+
While both `schedule.on` and a start listener task enable event-driven execution of workflows, they serve distinct purposes and have different implications:
165+
166+
- **`schedule.on`**: This property defines when a new workflow instance should be created based on an external event. When an event matches the criteria specified in `schedule.on`, a new workflow instance is initiated. The critical point here is that `schedule.on` solely manages the creation of new workflow instances. Any faults or timeouts related to the scheduling process are typically invisible to the user and do not impact the workflow instance.
167+
168+
- **Start `listen` task**: A start listener task defines a task that must be undertaken after a new workflow instance has been created. This task listens for specific events and begins processing once the instance is active. The critical difference is that a start listener task operates within an already instantiated workflow. If a start listener task experiences a timeout or fault, it can cause the entire workflow instance to fail or behave unexpectedly, directly impacting the flow's execution and outcome.
169+
170+
While `schedule.on` is concerned with *when* a new workflow instance should be initiated, a start listener task deals with *what* should happen once the instance is active. This distinction is crucial because it influences how errors and timeouts are handled—`schedule.on` faults are typically invisible and do not affect the workflow, whereas start listener task failures can directly and potentially severely impact the workflow instance they belong to.
171+
153172
### Task Flow
154173

155174
A workflow begins with the first task defined.

examples/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Examples
2+
3+
Welcome to the Serverless Workflow Examples directory! This section contains a collection of brief YAML files, each representing a single workflow definition.
4+
5+
These examples are designed to demonstrate specific features and functionalities of the Serverless Workflow DSL. They serve as a practical reference to help you understand and implement different aspects of Serverless Workflows in your projects.
6+
7+
## Contributing
8+
9+
We welcome contributions! If you have an example demonstrating a unique feature or use case of Serverless Workflow, feel free to submit a pull request.
10+
11+
For more detailed information on contributing, including guidelines and best practices, please refer to our [Contributing Guide](./CONTRIBUTING.md).

examples/bearer-auth-uri-format.yaml renamed to examples/authentication-bearer.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ do:
1212
uri: https://petstore.swagger.io/v2/pet/1
1313
authentication:
1414
bearer:
15-
token: ${ .token }
15+
token: ${ .token }

examples/authentication-oauth2.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: examples
4+
name: oauth2-authentication
5+
version: 1.0.0-alpha1
6+
do:
7+
- getPet:
8+
call: http
9+
with:
10+
method: get
11+
endpoint:
12+
uri: https://petstore.swagger.io/v2/pet/{petId}
13+
authentication:
14+
oauth2:
15+
authority: http://keycloak/realms/fake-authority
16+
endpoints: #optional
17+
token: /auth/token #defaults to /oauth2/token
18+
introspection: /auth/introspect #defaults to /oauth2/introspect
19+
grant: client_credentials
20+
client:
21+
id: workflow-runtime-id
22+
secret: workflow-runtime-secret

examples/authentication-oidc.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: examples
4+
name: oidc-authentication
5+
version: 1.0.0-alpha1
6+
do:
7+
- getPet:
8+
call: http
9+
with:
10+
method: get
11+
endpoint:
12+
uri: https://petstore.swagger.io/v2/pet/{petId}
13+
authentication:
14+
oidc:
15+
authority: http://keycloak/realms/fake-authority #endpoints are resolved using the OIDC configuration located at '/.well-known/openid-configuration'
16+
grant: client_credentials
17+
client:
18+
id: workflow-runtime-id
19+
secret: workflow-runtime-secret
File renamed without changes.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
document:
2+
dsl: '1.0.0'
3+
namespace: samples
4+
name: call-custom-function-cataloged
5+
version: '1.0.0'
6+
do:
7+
- log:
8+
call: https://raw.githubusercontent.com/serverlessworkflow/catalog/main/functions/log/1.0.0/function.yaml
9+
with:
10+
message: Hello, world!
11+
level: information
12+
timestamp: true
13+
format: '{TIMESTAMP} [{LEVEL}] ({CONTEXT}): {MESSAGE}'
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
document:
2+
dsl: '1.0.0'
3+
namespace: samples
4+
name: call-custom-function-inline
5+
version: '1.0.0'
6+
use:
7+
functions:
8+
getPetById:
9+
input:
10+
schema:
11+
document:
12+
type: object
13+
properties:
14+
petId:
15+
type: string
16+
required: [ petId ]
17+
call: http
18+
with:
19+
method: get
20+
endpoint: https://petstore.swagger.io/v2/pet/{petId}
21+
do:
22+
- getPet:
23+
call: getPetById
24+
with:
25+
petId: 69

examples/call-grpc.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
document:
2+
dsl: '1.0.0-alpha1'
3+
namespace: test
4+
name: grpc-example
5+
version: '0.1.0'
6+
do:
7+
- greet:
8+
call: grpc
9+
with:
10+
proto:
11+
endpoint: file://app/greet.proto
12+
service:
13+
name: GreeterApi.Greeter
14+
host: localhost
15+
port: 5011
16+
method: SayHello
17+
arguments:
18+
name: ${ .user.preferredDisplayName }
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: examples
4+
name: call-http-shorthand-endpoint
5+
version: 1.0.0-alpha1
6+
do:
7+
- getPet:
8+
call: http
9+
with:
10+
method: get
11+
endpoint: ${ "https://petstore.swagger.io/v2/pet/\(.petId)" }

0 commit comments

Comments
 (0)