Skip to content

Commit fc7c103

Browse files
authored
Merge pull request #45 from serverlessworkflow/feat-refactor
Removed strong-typed enumerations to support extensions
2 parents c1f49b8 + 50f05b5 commit fc7c103

File tree

310 files changed

+14900
-21860
lines changed

Some content is hidden

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

310 files changed

+14900
-21860
lines changed

.editorconfig

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
[*.{cs,vb}]
3+
#### Naming styles ####
4+
5+
# Naming rules
6+
7+
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
8+
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
9+
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
10+
11+
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
12+
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
13+
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
14+
15+
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
16+
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
17+
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
18+
19+
# Symbol specifications
20+
21+
dotnet_naming_symbols.interface.applicable_kinds = interface
22+
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
23+
dotnet_naming_symbols.interface.required_modifiers =
24+
25+
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
26+
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
27+
dotnet_naming_symbols.types.required_modifiers =
28+
29+
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
30+
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
31+
dotnet_naming_symbols.non_field_members.required_modifiers =
32+
33+
# Naming styles
34+
35+
dotnet_naming_style.begins_with_i.required_prefix = I
36+
dotnet_naming_style.begins_with_i.required_suffix =
37+
dotnet_naming_style.begins_with_i.word_separator =
38+
dotnet_naming_style.begins_with_i.capitalization = pascal_case
39+
40+
dotnet_naming_style.pascal_case.required_prefix =
41+
dotnet_naming_style.pascal_case.required_suffix =
42+
dotnet_naming_style.pascal_case.word_separator =
43+
dotnet_naming_style.pascal_case.capitalization = pascal_case
44+
45+
dotnet_naming_style.pascal_case.required_prefix =
46+
dotnet_naming_style.pascal_case.required_suffix =
47+
dotnet_naming_style.pascal_case.word_separator =
48+
dotnet_naming_style.pascal_case.capitalization = pascal_case
49+
dotnet_style_operator_placement_when_wrapping = beginning_of_line
50+
tab_width = 4
51+
indent_size = 4
52+
end_of_line = crlf
53+
dotnet_style_coalesce_expression = true:suggestion
54+
dotnet_style_null_propagation = true:suggestion
55+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
56+
dotnet_style_prefer_auto_properties = true:silent
57+
dotnet_style_object_initializer = true:suggestion
58+
dotnet_style_collection_initializer = true:suggestion
59+
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
60+
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
61+
dotnet_style_prefer_conditional_expression_over_return = true:silent
62+
dotnet_style_explicit_tuple_names = true:suggestion
63+
dotnet_style_prefer_inferred_tuple_names = true:suggestion
64+
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
65+
dotnet_style_prefer_compound_assignment = true:suggestion
66+
dotnet_style_prefer_simplified_interpolation = true:suggestion
67+
dotnet_style_namespace_match_folder = true:suggestion
68+
dotnet_style_readonly_field = true:suggestion
69+
70+
[*.cs]
71+
csharp_indent_labels = one_less_than_current
72+
csharp_space_around_binary_operators = before_and_after
73+
csharp_using_directive_placement = outside_namespace:silent
74+
csharp_prefer_simple_using_statement = true:suggestion
75+
csharp_prefer_braces = true:silent
76+
csharp_style_namespace_declarations = block_scoped:silent
77+
csharp_style_prefer_method_group_conversion = true:silent
78+
csharp_style_prefer_top_level_statements = true:silent
79+
csharp_style_expression_bodied_methods = false:silent
80+
csharp_style_expression_bodied_constructors = false:silent
81+
csharp_style_expression_bodied_operators = false:silent
82+
csharp_style_expression_bodied_properties = true:silent
83+
csharp_style_expression_bodied_indexers = true:silent
84+
csharp_style_expression_bodied_accessors = true:silent
85+
csharp_style_expression_bodied_lambdas = true:silent
86+
csharp_style_expression_bodied_local_functions = false:silent
87+
csharp_style_throw_expression = true:suggestion
88+
csharp_style_prefer_null_check_over_type_check = true:suggestion
89+
csharp_prefer_simple_default_expression = true:suggestion
90+
csharp_style_prefer_local_over_anonymous_function = true:suggestion
91+
csharp_style_prefer_index_operator = true:suggestion
92+
csharp_style_prefer_range_operator = true:suggestion
93+
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
94+
csharp_style_prefer_tuple_swap = true:suggestion
95+
csharp_style_prefer_utf8_string_literals = true:suggestion
96+
csharp_style_inlined_variable_declaration = true:suggestion
97+
csharp_style_deconstructed_variable_declaration = true:suggestion
98+
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
99+
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
100+
101+
file_header_template = Copyright © 2023-Present The Serverless Workflow Specification Authors\n\nLicensed under the Apache License, Version 2.0 (the "License"),\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.

README.md

Lines changed: 161 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
# Serverless Workflow Specification - .NET SDK
55

6-
Provides .NET 6.0 API/SPI and Model Validation for the [Serverless Workflow Specification](https://github.com/serverlessworkflow/specification)
6+
Provides .NET 7.0 API/SPI and Model Validation for the [Serverless Workflow Specification](https://github.com/serverlessworkflow/specification)
77

88
With the SDK, you can:
99

@@ -15,7 +15,7 @@ With the SDK, you can:
1515

1616
| Latest Releases | Conformance to spec version |
1717
| :---: | :---: |
18-
| [0.8.0.10](https://github.com/serverlessworkflow/sdk-net/releases/) | [v0.8](https://github.com/serverlessworkflow/specification/tree/0.8.x) |
18+
| [0.8.7](https://github.com/serverlessworkflow/sdk-net/releases/) | [0.8](https://github.com/serverlessworkflow/specification/tree/0.8.x) |
1919

2020
### Getting Started
2121

@@ -27,9 +27,9 @@ dotnet nuget add package ServerlessWorkflow.Sdk
2727
services.AddServerlessWorkflow();
2828
```
2929

30-
### How to use
30+
### Usage
3131

32-
#### Building workflows programatically
32+
#### Build workflows programatically
3333

3434
```csharp
3535
var workflow = WorkflowDefinition.Create("MyWorkflow", "MyWorkflow", "1.0")
@@ -60,7 +60,7 @@ var workflow = WorkflowDefinition.Create("MyWorkflow", "MyWorkflow", "1.0")
6060
.Build();
6161
```
6262

63-
#### Reading workflows
63+
#### Read workflows
6464

6565
```csharp
6666
var reader = WorkflowReader.Create();
@@ -70,7 +70,7 @@ using(Stream stream = File.OpenRead("myWorkflow.json"))
7070
}
7171
```
7272

73-
#### Writing workflows
73+
#### Write workflows
7474

7575
```csharp
7676
var writer = WorkflowWriter.Create();
@@ -88,9 +88,163 @@ using(Stream stream = File.OpenRead("myWorkflow.json"))
8888
}
8989
```
9090

91-
#### Validating workflows
91+
#### Validate workflows
9292

9393
```csharp
9494
var validator = serviceProvider.GetRequiredService<IValidator<WorkflowDefinition>>();
9595
var validationResult = validator.Validate(myWorkflow);
9696
```
97+
98+
#### Extend Workflows
99+
100+
The SDK allows extending the Serverless Workflow in two ways, possibly combined: via metadata and via extensions.
101+
102+
#### Metadata
103+
104+
Workflow components that support metadata, such as `WorkflowDefinition` or `StateDefinition`, expose a `metadata` property,
105+
which is a dynamic name/value mapping of properties used to enrich the serverless workflow model with information beyond its core definitions.
106+
107+
It has the advantage of being an easy, cross-compatible way of declaring additional data, but lacks well-defined, well-documented schema of the data, thus loosing the ability to validate it
108+
without custom implementation.
109+
110+
*Adding metadata to a workflow:*
111+
```csharp
112+
var workflow = new WorkflowBuilder()
113+
...
114+
.WithMetadata(new Dictionary<string, object>() { { "metadataPropertyName", metadataPropertyValue } })
115+
...
116+
.Build();
117+
```
118+
119+
*Resulting workflow:*
120+
121+
```yaml
122+
id: sample-workflow
123+
version: 1.0.0
124+
specVersion: 0.8
125+
metadata:
126+
metadataPropertyName: metadataPropertyValue #added to the metadata property of supporting components
127+
...
128+
```
129+
130+
131+
#### Extension
132+
133+
Users have the ability to define extensions, providing the ability to extend, override or replace parts of the Serverless Workflow schema.
134+
135+
To do so, you must first create a file containing the JsonSchema of your extension, then reference it in your workflow definition.
136+
137+
*Schema of a sample extension that adds a new `greet` `functionType`:*
138+
<table>
139+
<tr>
140+
<th>JSON</th>
141+
<th>YAML</th>
142+
</tr>
143+
<tr>
144+
<td valign="top">
145+
146+
```json
147+
{
148+
"$defs": {
149+
"functions": {
150+
"definitions": {
151+
"function": {
152+
"type": "object",
153+
"properties": {
154+
"type": {
155+
"type": "string",
156+
"description": "Defines the function type. Is either `rest`, `asyncapi, `rpc`, `graphql`, `odata`, `expression` or `greet`. Default is `rest`",
157+
"enum": [
158+
"rest",
159+
"asyncapi",
160+
"rpc",
161+
"graphql",
162+
"odata",
163+
"expression",
164+
"custom",
165+
"greet"
166+
],
167+
"default": "rest"
168+
}
169+
}
170+
}
171+
}
172+
}
173+
}
174+
}
175+
```
176+
177+
</td>
178+
179+
<td valign="top">
180+
181+
```yaml
182+
'$defs':
183+
functions:
184+
definitions:
185+
function:
186+
type: object
187+
properties:
188+
type:
189+
type: string
190+
description: Defines the function type. Is either `rest`, `asyncapi, `rpc`,
191+
`graphql`, `odata`, `expression` or `greet`. Default is `rest`
192+
enum:
193+
- rest
194+
- asyncapi
195+
- rpc
196+
- graphql
197+
- odata
198+
- expression
199+
- custom
200+
- greet
201+
default: rest
202+
```
203+
204+
</td>
205+
</tr>
206+
</table>
207+
208+
The above example refers to `/$defs/functions`, because upon validation the SDK bundles all the Serverless Workflow Specification's schemas into the `$defs` property of a single schema.
209+
210+
*In this case, `functions` is the extensionless name of the schema file we want to override (https://serverlessworkflow.io/schemas/latest/functions.json).
211+
212+
A [Json Merge Patch](https://datatracker.ietf.org/doc/html/rfc7386) is performed sequentially on the bundled schema with the defined extensions, in declaring order.
213+
214+
*In this case, the above schema will patch the object defined at `/functions/definitions/function` in file https://serverlessworkflow.io/schemas/latest/functions.json*
215+
216+
*Extending a workflow:*
217+
```csharp
218+
var workflow = new WorkflowBuilder()
219+
.WithId("sample-extended")
220+
.WithName("Sample Extended Workflow")
221+
.WithVersion("1.0.0")
222+
.UseSpecVersion(ServerlessWorkflowSpecVersion.V08)
223+
.UseExtension("extensionId", new Uri("file://.../extensions/greet-function-type.json"))
224+
.StartsWith("do-work", flow => flow.Execute("greet", action => action
225+
.Invoke(function => function
226+
.OfType("greet")
227+
.WithName("greet")
228+
.ForOperation("#"))))
229+
.End()
230+
.Build();
231+
```
232+
233+
*Adding extension properties:*
234+
```csharp
235+
var workflow = new WorkflowBuilder()
236+
...
237+
.WithExtensionProperty("extensionPropertyName", propertyValue } })
238+
...
239+
.Build();
240+
```
241+
242+
*Resulting workflow:*
243+
244+
```yaml
245+
id: sample-workflow
246+
version: 1.0.0
247+
specVersion: 0.8
248+
extensionPropertyName: propertyValue #added as top level property of extended component, as opposed to metadata
249+
...
250+
```

ServerlessWorkflow.Sdk.sln

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,53 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.31019.35
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.4.33213.308
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerlessWorkflow.Sdk", "src\ServerlessWorkflow.Sdk\ServerlessWorkflow.Sdk.csproj", "{E174F5CC-F3DC-4370-AAC1-AC1D7724C792}"
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9016CF88-4100-425F-9E1A-B6099F55A35B}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerlessWorkflow.Sdk.UnitTests", "src\ServerlessWorkflow.Sdk.UnitTests\ServerlessWorkflow.Sdk.UnitTests.csproj", "{70AD35E0-0C14-4EBF-A841-B0D084392753}"
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{60FE2678-84CF-492C-950D-3485582F6712}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{0CD38EC5-C4AB-491A-B6EA-D6C608F68157}"
11+
ProjectSection(SolutionItems) = preProject
12+
code-of-conduct.md = code-of-conduct.md
13+
CONTRIBUTING.md = CONTRIBUTING.md
14+
LICENSE = LICENSE
15+
MAINTAINERS.md = MAINTAINERS.md
16+
maintainer_guidelines.md = maintainer_guidelines.md
17+
README.md = README.md
18+
EndProjectSection
19+
EndProject
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerlessWorkflow.Sdk", "src\ServerlessWorkflow.Sdk\ServerlessWorkflow.Sdk.csproj", "{1C104B2C-A3E8-4CB9-AE1D-28370B7A705D}"
21+
EndProject
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerlessWorkflow.Sdk.UnitTests", "tests\ServerlessWorkflow.Sdk.UnitTests\ServerlessWorkflow.Sdk.UnitTests.csproj", "{F1575E10-B57B-4012-97FF-AF942A558D7C}"
23+
EndProject
24+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution", "solution", "{F3B6D944-46DA-4CAF-A8BE-0C8F230869F9}"
25+
ProjectSection(SolutionItems) = preProject
26+
.editorconfig = .editorconfig
27+
EndProjectSection
928
EndProject
1029
Global
1130
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1231
Debug|Any CPU = Debug|Any CPU
1332
Release|Any CPU = Release|Any CPU
1433
EndGlobalSection
1534
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16-
{E174F5CC-F3DC-4370-AAC1-AC1D7724C792}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17-
{E174F5CC-F3DC-4370-AAC1-AC1D7724C792}.Debug|Any CPU.Build.0 = Debug|Any CPU
18-
{E174F5CC-F3DC-4370-AAC1-AC1D7724C792}.Release|Any CPU.ActiveCfg = Release|Any CPU
19-
{E174F5CC-F3DC-4370-AAC1-AC1D7724C792}.Release|Any CPU.Build.0 = Release|Any CPU
20-
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21-
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Debug|Any CPU.Build.0 = Debug|Any CPU
22-
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Release|Any CPU.ActiveCfg = Release|Any CPU
23-
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Release|Any CPU.Build.0 = Release|Any CPU
35+
{1C104B2C-A3E8-4CB9-AE1D-28370B7A705D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36+
{1C104B2C-A3E8-4CB9-AE1D-28370B7A705D}.Debug|Any CPU.Build.0 = Debug|Any CPU
37+
{1C104B2C-A3E8-4CB9-AE1D-28370B7A705D}.Release|Any CPU.ActiveCfg = Release|Any CPU
38+
{1C104B2C-A3E8-4CB9-AE1D-28370B7A705D}.Release|Any CPU.Build.0 = Release|Any CPU
39+
{F1575E10-B57B-4012-97FF-AF942A558D7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40+
{F1575E10-B57B-4012-97FF-AF942A558D7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
41+
{F1575E10-B57B-4012-97FF-AF942A558D7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
42+
{F1575E10-B57B-4012-97FF-AF942A558D7C}.Release|Any CPU.Build.0 = Release|Any CPU
2443
EndGlobalSection
2544
GlobalSection(SolutionProperties) = preSolution
2645
HideSolutionNode = FALSE
2746
EndGlobalSection
47+
GlobalSection(NestedProjects) = preSolution
48+
{1C104B2C-A3E8-4CB9-AE1D-28370B7A705D} = {9016CF88-4100-425F-9E1A-B6099F55A35B}
49+
{F1575E10-B57B-4012-97FF-AF942A558D7C} = {60FE2678-84CF-492C-950D-3485582F6712}
50+
EndGlobalSection
2851
GlobalSection(ExtensibilityGlobals) = postSolution
2952
SolutionGuid = {1402FB0B-4169-41A6-A372-DA260E79481B}
3053
EndGlobalSection

0 commit comments

Comments
 (0)