diff --git a/.github/workflows/build-dotnet.yml b/.github/workflows/build-dotnet.yml index b8c1597..4ad7306 100644 --- a/.github/workflows/build-dotnet.yml +++ b/.github/workflows/build-dotnet.yml @@ -16,10 +16,6 @@ env: jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - dotnet-version: ['9.0.x' ] - steps: - name: Checkout uses: actions/checkout@v3 @@ -32,10 +28,12 @@ jobs: git fetch git pull - - name: Setup .NET ${{ matrix.dotnet-version }} + - name: Setup .NET uses: actions/setup-dotnet@v2 with: - dotnet-version: ${{ matrix.dotnet-version }} + dotnet-version: | + 8.0.x + 9.0.x - name: Restore dependencies run: dotnet restore "${{ env.SOLUTION }}" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ba4d95e..92fcc69 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,7 +17,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v1 with: - dotnet-version: 9.0.x + dotnet-version: | + 8.0.x + 9.0.x - name: Restore dependencies run: dotnet restore "${{ env.SOLUTION }}" - name: Build diff --git a/.github/workflows/test-dotnet.yml b/.github/workflows/test-dotnet.yml index c51309e..88a2a30 100644 --- a/.github/workflows/test-dotnet.yml +++ b/.github/workflows/test-dotnet.yml @@ -16,18 +16,16 @@ env: jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - dotnet-version: ['9.0.x' ] - steps: - name: Checkout uses: actions/checkout@v3 - - name: Setup .NET ${{ matrix.dotnet-version }} + - name: Setup .NET uses: actions/setup-dotnet@v2 with: - dotnet-version: ${{ matrix.dotnet-version }} + dotnet-version: | + 8.0.x + 9.0.x - name: Restore dependencies run: dotnet restore "${{ env.SOLUTION }}" diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..8613eec --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,27 @@ +# Security Policy + +## Reporting a Vulnerability + +The Serverless Workflow .NET SDK team and community take security vulnerabilities very seriously. Responsible disclosure of security issues is greatly appreciated, and every effort will be made to acknowledge and address your findings. + +To report a security issue: + +- **Use the GitHub Security Advisory**: Please use the ["Report a Vulnerability"](https://github.com/serverlessworkflow/sdk-net/security/advisories/new) tab on GitHub to submit your report. + +The team will acknowledge your report and provide details on the next steps. After the initial response, the security team will keep you informed of the progress towards a fix and any subsequent announcements. Additional information or guidance may be requested as necessary. + +## Security Best Practices + +To ensure the security and stability of the Serverless Workflow .NET SDK, consider the following best practices: + +- **Runtime Environment Hardening**: Secure the underlying infrastructure where the SDK is used. This includes using up-to-date operating systems, applying security patches regularly, and configuring firewalls and security groups to limit access to only necessary ports and services. + +- **Secure Configuration Management**: Ensure that configuration files, especially those containing sensitive information like API keys, connection strings, or certificates, are stored securely. Use environment variables, secret management tools, or configuration providers to avoid hardcoding sensitive data in your application. + +- **Dependency Management**: Regularly audit and update dependencies used in your project. Use tools like [Dependabot](https://github.com/dependabot) or similar dependency management solutions to identify vulnerabilities in third-party NuGet packages and address them promptly. + +By adhering to these best practices, the security of workflows and applications built using the Serverless Workflow .NET SDK can be significantly enhanced, reducing the risk of vulnerabilities and ensuring the integrity and reliability of the workflows executed. + +--- + +Thank you for contributing to the security and integrity of the Serverless Workflow .NET SDK! diff --git a/src/ServerlessWorkflow.Sdk.Builders/ContainerProcessDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/ContainerProcessDefinitionBuilder.cs index c157e7d..60355d3 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/ContainerProcessDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/ContainerProcessDefinitionBuilder.cs @@ -28,6 +28,11 @@ public class ContainerProcessDefinitionBuilder /// protected virtual string? Image { get; set; } + /// + /// Gets/sets the name of the container to run + /// + protected virtual string? Name { get; set; } + /// /// Gets/sets the command, if any, to execute on the container /// @@ -56,6 +61,14 @@ public virtual IContainerProcessDefinitionBuilder WithImage(string image) return this; } + /// + public virtual IContainerProcessDefinitionBuilder WithName(string name) + { + ArgumentException.ThrowIfNullOrWhiteSpace(name); + this.Name = name; + return this; + } + /// public virtual IContainerProcessDefinitionBuilder WithCommand(string command) { @@ -122,6 +135,7 @@ public override ContainerProcessDefinition Build() return new() { Image = this.Image, + Name = this.Name, Command = this.Command, Ports = this.Ports, Volumes = this.Volumes, diff --git a/src/ServerlessWorkflow.Sdk.Builders/InputDataModelDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/InputDataModelDefinitionBuilder.cs new file mode 100644 index 0000000..589a4fb --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/InputDataModelDefinitionBuilder.cs @@ -0,0 +1,49 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Represents the default implementation of the interface +/// +public class InputDataModelDefinitionBuilder + : IInputDataModelDefinitionBuilder +{ + + /// + /// Gets the to configure + /// + protected InputDataModelDefinition Input { get; } = new(); + + /// + public virtual IInputDataModelDefinitionBuilder From(object expression) + { + ArgumentNullException.ThrowIfNull(expression); + this.Input.From = expression; + return this; + } + + /// + public virtual IInputDataModelDefinitionBuilder WithSchema(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new SchemaDefinitionBuilder(); + setup(builder); + this.Input.Schema = builder.Build(); + return this; + } + + /// + public virtual InputDataModelDefinition Build() => this.Input; + +} diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IContainerProcessDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IContainerProcessDefinitionBuilder.cs index afe3ade..112e935 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IContainerProcessDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IContainerProcessDefinitionBuilder.cs @@ -29,6 +29,13 @@ public interface IContainerProcessDefinitionBuilder /// The configured IContainerProcessDefinitionBuilder WithImage(string image); + /// + /// Configures the container to use the specified name + /// + /// The container's name + /// The configured + IContainerProcessDefinitionBuilder WithName(string name); + /// /// Configures the command, if any, to execute on the container /// diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IInputDataModelDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IInputDataModelDefinitionBuilder.cs new file mode 100644 index 0000000..1be73a4 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IInputDataModelDefinitionBuilder.cs @@ -0,0 +1,42 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Defines the fundamentals of a service used to build s +/// +public interface IInputDataModelDefinitionBuilder +{ + + /// + /// Configures the input data schema + /// + /// An used to configure the input data schema + /// The configured + IInputDataModelDefinitionBuilder WithSchema(Action setup); + + /// + /// Configures the runtime expression used to filter the input data + /// + /// The runtime expression used to filter the input data + /// The configured + IInputDataModelDefinitionBuilder From(object expression); + + /// + /// Builds the configured + /// + /// A new + InputDataModelDefinition Build(); + +} diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenTaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenTaskDefinitionBuilder.cs index 0975bd7..5850ec8 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenTaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenTaskDefinitionBuilder.cs @@ -25,6 +25,13 @@ public interface IListenTaskDefinitionBuilder /// /// An used to setup the task's listener target /// The configured - IListenTaskDefinitionBuilder To(Action setup); + IListenTaskDefinitionBuilder To(Action setup); + + /// + /// Configures the iterator used to process each consumed event + /// + /// An used to configure the to use + /// The configured + IListenTaskDefinitionBuilder Foreach(Action setup); } diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerDefinitionBuilder.cs index b30dbd1..9fd072c 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerDefinitionBuilder.cs @@ -17,19 +17,20 @@ namespace ServerlessWorkflow.Sdk.Builders; /// Defines the fundamentals of a service used to build s /// public interface IListenerDefinitionBuilder + : IListenerTargetDefinitionBuilder { /// - /// Configures the + /// Configures how to read consumed events /// - /// - /// - IListenerDefinitionBuilder To(Action setup); + /// Specifies how consumed events should be read. See s + /// The configured + IListenerDefinitionBuilder Read(string readMode); /// /// Builds the configured /// /// A new - ListenerDefinition Build(); + new ListenerDefinition Build(); } \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerTargetDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerTargetDefinitionBuilder.cs index 45a558c..ae9ddd2 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerTargetDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IListenerTargetDefinitionBuilder.cs @@ -37,6 +37,18 @@ public interface IListenerTargetDefinitionBuilder /// A new IEventFilterDefinitionBuilder One(); + /// + /// Configures the task to listen to any events until the specified condition expression matches + /// + /// A runtime expression that represents the condition that must match for the task to stop consuming events + void Until(string expression); + + /// + /// Configures the task to listen to any events until the specified events are consumed + /// + /// An used to configure the events to consume for the task to stop consuming events + void Until(Action setup); + /// /// Builds the configured /// diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IOutputDataModelDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IOutputDataModelDefinitionBuilder.cs new file mode 100644 index 0000000..464deb5 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IOutputDataModelDefinitionBuilder.cs @@ -0,0 +1,42 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Defines the fundamentals of a service used to build s +/// +public interface IOutputDataModelDefinitionBuilder +{ + + /// + /// Configures the output data schema + /// + /// An used to configure the output data schema + /// The configured + IOutputDataModelDefinitionBuilder WithSchema(Action setup); + + /// + /// Configures the runtime expression used to filter the data to output + /// + /// The runtime expression used to filter the data to output + /// The configured + IOutputDataModelDefinitionBuilder As(object expression); + + /// + /// Builds the configured + /// + /// A new + OutputDataModelDefinition Build(); + +} diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ISchemaDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ISchemaDefinitionBuilder.cs new file mode 100644 index 0000000..bacc732 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ISchemaDefinitionBuilder.cs @@ -0,0 +1,49 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Defines the fundamentals of a service used to build s +/// +public interface ISchemaDefinitionBuilder +{ + + /// + /// Sets the schema format + /// + /// The schema format + /// The configured + ISchemaDefinitionBuilder WithFormat(string format); + + /// + /// Sets the schema's + /// + /// An used to configure the schema's + /// The configured + ISchemaDefinitionBuilder WithResource(Action setup); + + /// + /// Sets the schema document + /// + /// The schema document + /// The configured + ISchemaDefinitionBuilder WithDocument(object document); + + /// + /// Builds the configured + /// + /// A new + SchemaDefinition Build(); + +} diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ISubscriptionIteratorDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ISubscriptionIteratorDefinitionBuilder.cs new file mode 100644 index 0000000..8ded995 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ISubscriptionIteratorDefinitionBuilder.cs @@ -0,0 +1,63 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Defines the fundamentals of a service used to build s +/// +public interface ISubscriptionIteratorDefinitionBuilder +{ + + /// + /// Sets the name of the variable used to store the item being enumerated + /// + /// The name of the variable used to store the item being enumerated + /// The configured + ISubscriptionIteratorDefinitionBuilder Item(string item); + + /// + /// Sets the name of the variable used to store the index of the item being enumerated + /// + /// The name of the variable used to store the index of the item being enumerated + /// The configured + ISubscriptionIteratorDefinitionBuilder At(string at); + + /// + /// Sets the tasks to execute for each event or message consumed + /// + /// An used to configure the tasks to execute for each event or message consumed + /// The configured + ISubscriptionIteratorDefinitionBuilder Do(Action setup); + + /// + /// Configures the output data of each item + /// + /// An used to configure the output data + /// The configured + ISubscriptionIteratorDefinitionBuilder Output(Action setup); + + /// + /// Configures the data exported by each item + /// + /// An used to configure the exported data + /// The configured + ISubscriptionIteratorDefinitionBuilder Export(Action setup); + + /// + /// Builds the configured + /// + /// A new + SubscriptionIteratorDefinition Build(); + +} diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs index bc4b32a..b7dac41 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/ITaskDefinitionBuilder.cs @@ -44,26 +44,47 @@ public interface ITaskDefinitionBuilder TBuilder If(string condition); /// - /// Sets the workflow's timeout + /// Sets the task's timeout /// - /// The name of the workflow's timeout + /// The name of the task's timeout /// The configured TBuilder WithTimeout(string name); /// - /// Sets the workflow's timeout + /// Sets the task's timeout /// - /// The workflow's timeout + /// The task's timeout /// The configured TBuilder WithTimeout(TimeoutDefinition timeout); /// - /// Sets the workflow's timeout + /// Sets the task's timeout /// - /// An used to setup the workflow's timeout + /// An used to setup the task's timeout /// The configured TBuilder WithTimeout(Action setup); + /// + /// Sets the task's input data + /// + /// An used to configure the task's input + /// The configured + TBuilder WithInput(Action setup); + + /// + /// Sets the task's output data + /// + /// An used to configure the task's output + /// The configured + TBuilder WithOutput(Action setup); + + /// + /// Sets the data exported by the task + /// + /// An used to configure the data exported by the task + /// The configured + TBuilder WithExport(Action setup); + /// /// Configures the task to build to then execute the specified flow directive /// diff --git a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IWorkflowDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IWorkflowDefinitionBuilder.cs index 7a6cfc5..ed94f05 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IWorkflowDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/Interfaces/IWorkflowDefinitionBuilder.cs @@ -98,6 +98,20 @@ public interface IWorkflowDefinitionBuilder /// The configured IWorkflowDefinitionBuilder WithTimeout(Action setup); + /// + /// Sets the workflow's input data + /// + /// An used to configure the workflow's input + /// The configured + IWorkflowDefinitionBuilder WithInput(Action setup); + + /// + /// Sets the workflow's output data + /// + /// An used to configure the workflow's output + /// The configured + IWorkflowDefinitionBuilder WithOutput(Action setup); + /// /// Uses the specified authentication policy /// diff --git a/src/ServerlessWorkflow.Sdk.Builders/ListenTaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/ListenTaskDefinitionBuilder.cs index 3512aa0..3893e1f 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/ListenTaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/ListenTaskDefinitionBuilder.cs @@ -21,31 +21,31 @@ public class ListenTaskDefinitionBuilder { /// - /// Gets/sets the task's listener configuration + /// Gets/sets the to configure /// - protected ListenerDefinition? Listener { get; set; } + protected ListenTaskDefinition Task { get; } = new() { Listen = null! }; /// - public virtual IListenTaskDefinitionBuilder To(Action setup) + public virtual IListenTaskDefinitionBuilder To(Action setup) { - var builder = new ListenerTargetDefinitionBuilder(); + ArgumentNullException.ThrowIfNull(setup); + var builder = new ListenerDefinitionBuilder(); setup(builder); - var target = builder.Build(); - this.Listener = new() - { - To = target - }; + this.Task.Listen = builder.Build(); return this; } /// - public override ListenTaskDefinition Build() + public virtual IListenTaskDefinitionBuilder Foreach(Action setup) { - if (this.Listener == null) throw new NullReferenceException("The listener must be set"); - return this.Configure(new() - { - Listen = this.Listener - }); + ArgumentNullException.ThrowIfNull(setup); + var builder = new SubscriptionIteratorDefinitionBuilder(); + setup(builder); + this.Task.Foreach = builder.Build(); + return this; } + /// + public override ListenTaskDefinition Build() => this.Configure(this.Task); + } \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk.Builders/ListenerDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/ListenerDefinitionBuilder.cs index 850af66..ebffd54 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/ListenerDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/ListenerDefinitionBuilder.cs @@ -16,33 +16,30 @@ namespace ServerlessWorkflow.Sdk.Builders; /// /// Represents the default implementation of the interface /// -/// The listener's target -public class ListenerDefinitionBuilder(EventConsumptionStrategyDefinition? target = null) - : IListenerDefinitionBuilder +/// The listener's target +public class ListenerDefinitionBuilder(EventConsumptionStrategyDefinition? to = null) + : ListenerTargetDefinitionBuilder, IListenerDefinitionBuilder { /// - /// Gets/sets the listener's target + /// Gets/sets the to configure /// - protected EventConsumptionStrategyDefinition? Target { get; set; } = target; + protected ListenerDefinition Listener { get; } = new() { To = to! }; /// - public virtual IListenerDefinitionBuilder To(Action setup) + public virtual IListenerDefinitionBuilder Read(string readMode) { - var builder = new ListenerTargetDefinitionBuilder(); - setup(builder); - this.Target = builder.Build(); + ArgumentException.ThrowIfNullOrWhiteSpace(readMode); + this.Listener.Read = readMode; return this; } /// - public virtual ListenerDefinition Build() + public virtual new ListenerDefinition Build() { - if (this.Target == null) throw new NullReferenceException("The listener's target must be set"); - return new() - { - To = this.Target - }; + var to = base.Build() ?? throw new NullReferenceException("The listener's target must be set"); + this.Listener.To = to; + return this.Listener; } } \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk.Builders/ListenerTargetDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/ListenerTargetDefinitionBuilder.cs index 16a1225..6e85dfe 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/ListenerTargetDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/ListenerTargetDefinitionBuilder.cs @@ -35,6 +35,16 @@ public class ListenerTargetDefinitionBuilder /// protected IEventFilterDefinitionBuilder? SingleEvent { get; set; } + /// + /// Gets the runtime expression that represents the condition that must match for the task to stop consuming events + /// + protected string? UntilExpression { get; private set; } + + /// + /// Gets the strategy used to configure the events to consume for the task to stop consuming events + /// + protected EventConsumptionStrategyDefinition? UntilEvents { get; private set; } + /// public virtual IEventFilterDefinitionCollectionBuilder All() { @@ -56,6 +66,24 @@ public virtual IEventFilterDefinitionBuilder One() return this.SingleEvent; } + /// + public virtual void Until(string expression) + { + ArgumentException.ThrowIfNullOrWhiteSpace(expression); + if (this.AnyEvents == null) throw new Exception("The until clause can only be specified when the strategy is used to consume any events"); + this.UntilExpression = expression; + } + + /// + public virtual void Until(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + if (this.AnyEvents == null) throw new Exception("The until clause can only be specified when the strategy is used to consume any events"); + var builder = new ListenerTargetDefinitionBuilder(); + setup(builder); + this.UntilEvents = builder.Build(); + } + /// public virtual EventConsumptionStrategyDefinition Build() { @@ -64,7 +92,9 @@ public virtual EventConsumptionStrategyDefinition Build() { All = this.AllEvents?.Build(), Any = this.AnyEvents?.Build(), - One = this.SingleEvent?.Build() + One = this.SingleEvent?.Build(), + UntilExpression = this.UntilExpression, + Until = this.UntilEvents }; } diff --git a/src/ServerlessWorkflow.Sdk.Builders/OAuth2AuthenticationClientDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/OAuth2AuthenticationClientDefinitionBuilder.cs index de4ddb0..41e5ba2 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/OAuth2AuthenticationClientDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/OAuth2AuthenticationClientDefinitionBuilder.cs @@ -43,7 +43,7 @@ public class OAuth2AuthenticationClientDefinitionBuilder /// public virtual IOAuth2AuthenticationClientDefinitionBuilder WithId(string id) { - ArgumentException.ThrowIfNullOrEmpty(id); + ArgumentException.ThrowIfNullOrWhiteSpace(id); this.Id = id; return this; } @@ -51,7 +51,7 @@ public virtual IOAuth2AuthenticationClientDefinitionBuilder WithId(string id) /// public virtual IOAuth2AuthenticationClientDefinitionBuilder WithSecret(string secret) { - ArgumentException.ThrowIfNullOrEmpty(secret); + ArgumentException.ThrowIfNullOrWhiteSpace(secret); this.Secret = secret; return this; } diff --git a/src/ServerlessWorkflow.Sdk.Builders/OutputDataModelDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/OutputDataModelDefinitionBuilder.cs new file mode 100644 index 0000000..0e39803 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/OutputDataModelDefinitionBuilder.cs @@ -0,0 +1,49 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Represents the default implementation of the interface +/// +public class OutputDataModelDefinitionBuilder + : IOutputDataModelDefinitionBuilder +{ + + /// + /// Gets the to configure + /// + protected OutputDataModelDefinition Output { get; } = new(); + + /// + public virtual IOutputDataModelDefinitionBuilder As(object expression) + { + ArgumentNullException.ThrowIfNull(expression); + this.Output.As = expression; + return this; + } + + /// + public virtual IOutputDataModelDefinitionBuilder WithSchema(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new SchemaDefinitionBuilder(); + setup(builder); + this.Output.Schema = builder.Build(); + return this; + } + + /// + public virtual OutputDataModelDefinition Build() => this.Output; + +} \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk.Builders/SchemaDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/SchemaDefinitionBuilder.cs new file mode 100644 index 0000000..40e71bc --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/SchemaDefinitionBuilder.cs @@ -0,0 +1,57 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Represents the default implementation of the interface +/// +public class SchemaDefinitionBuilder + : ISchemaDefinitionBuilder +{ + + /// + /// Gets the to configure + /// + protected SchemaDefinition Schema { get; } = new(); + + /// + public virtual ISchemaDefinitionBuilder WithFormat(string format) + { + ArgumentException.ThrowIfNullOrWhiteSpace(format); + this.Schema.Format = format; + return this; + } + + /// + public virtual ISchemaDefinitionBuilder WithResource(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new ExternalResourceDefinitionBuilder(); + setup(builder); + this.Schema.Resource = builder.Build(); + return this; + } + + /// + public virtual ISchemaDefinitionBuilder WithDocument(object document) + { + ArgumentNullException.ThrowIfNull(document); + this.Schema.Document = document; + return this; + } + + /// + public virtual SchemaDefinition Build() => this.Schema; + +} diff --git a/src/ServerlessWorkflow.Sdk.Builders/ServerlessWorkflow.Sdk.Builders.csproj b/src/ServerlessWorkflow.Sdk.Builders/ServerlessWorkflow.Sdk.Builders.csproj index ee72792..eccdd43 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/ServerlessWorkflow.Sdk.Builders.csproj +++ b/src/ServerlessWorkflow.Sdk.Builders/ServerlessWorkflow.Sdk.Builders.csproj @@ -1,11 +1,10 @@ - net9.0 + net8.0;net9.0 enable enable - 1.0.0 - alpha5.4 + 1.0.1 $(VersionPrefix) $(VersionPrefix) en diff --git a/src/ServerlessWorkflow.Sdk.Builders/SubscriptionIteratorDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/SubscriptionIteratorDefinitionBuilder.cs new file mode 100644 index 0000000..40954c9 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk.Builders/SubscriptionIteratorDefinitionBuilder.cs @@ -0,0 +1,77 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Builders; + +/// +/// Represents the default implementation of the interface +/// +public class SubscriptionIteratorDefinitionBuilder + : ISubscriptionIteratorDefinitionBuilder +{ + + /// + /// Gets the to configure + /// + protected SubscriptionIteratorDefinition Iterator { get; } = new(); + + /// + public virtual ISubscriptionIteratorDefinitionBuilder Item(string item) + { + ArgumentException.ThrowIfNullOrWhiteSpace(item); + this.Iterator.Item = item; + return this; + } + + /// + public virtual ISubscriptionIteratorDefinitionBuilder At(string at) + { + ArgumentException.ThrowIfNullOrWhiteSpace(at); + this.Iterator.At = at; + return this; + } + + /// + public virtual ISubscriptionIteratorDefinitionBuilder Do(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new TaskDefinitionMapBuilder(); + setup(builder); + this.Iterator.Do = builder.Build(); + return this; + } + + /// + public virtual ISubscriptionIteratorDefinitionBuilder Output(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new OutputDataModelDefinitionBuilder(); + setup(builder); + this.Iterator.Output = builder.Build(); + return this; + } + + /// + public virtual ISubscriptionIteratorDefinitionBuilder Export(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new OutputDataModelDefinitionBuilder(); + setup(builder); + this.Iterator.Export = builder.Build(); + return this; + } + + /// + public virtual SubscriptionIteratorDefinition Build() => this.Iterator; + +} \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs index 3e0834b..697e67b 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/TaskDefinitionBuilder.cs @@ -34,6 +34,21 @@ public abstract class TaskDefinitionBuilder /// protected OneOf? Timeout { get; set; } + /// + /// Gets/sets the task's input data, if any + /// + protected InputDataModelDefinition? Input { get; set; } + + /// + /// Gets/sets the task's output data, if any + /// + protected OutputDataModelDefinition? Output { get; set; } + + /// + /// Gets/sets the task's export data, if any + /// + protected OutputDataModelDefinition? Export { get; set; } + /// /// Gets/sets the flow directive, if any, used to then execute /// @@ -73,6 +88,36 @@ public virtual TBuilder WithTimeout(Action setup) return (TBuilder)(object)this; } + /// + public virtual TBuilder WithInput(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new InputDataModelDefinitionBuilder(); + setup(builder); + this.Input = builder.Build(); + return (TBuilder)(object)this; + } + + /// + public virtual TBuilder WithOutput(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new OutputDataModelDefinitionBuilder(); + setup(builder); + this.Output = builder.Build(); + return (TBuilder)(object)this; + } + + /// + public virtual TBuilder WithExport(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new OutputDataModelDefinitionBuilder(); + setup(builder); + this.Export = builder.Build(); + return (TBuilder)(object)this; + } + /// public virtual TBuilder Then(string directive) { @@ -95,6 +140,9 @@ protected virtual TDefinition Configure(TDefinition definition) else definition.TimeoutReference = this.Timeout.T2Value; } definition.Then = this.ThenDirective; + definition.Input = this.Input; + definition.Output = this.Output; + definition.Export = this.Export; return definition; } diff --git a/src/ServerlessWorkflow.Sdk.Builders/WorkflowDefinitionBuilder.cs b/src/ServerlessWorkflow.Sdk.Builders/WorkflowDefinitionBuilder.cs index 4a41a88..96995be 100644 --- a/src/ServerlessWorkflow.Sdk.Builders/WorkflowDefinitionBuilder.cs +++ b/src/ServerlessWorkflow.Sdk.Builders/WorkflowDefinitionBuilder.cs @@ -63,6 +63,16 @@ public class WorkflowDefinitionBuilder /// protected OneOf? Timeout { get; set; } + /// + /// Gets/sets the workflow's input data, if any + /// + protected InputDataModelDefinition? Input { get; set; } + + /// + /// Gets/sets the workflow's output data, if any + /// + protected OutputDataModelDefinition? Output { get; set; } + /// /// Gets/sets a name/value mapping of the workflow's reusable components /// @@ -166,6 +176,26 @@ public virtual IWorkflowDefinitionBuilder WithTimeout(Action + public virtual IWorkflowDefinitionBuilder WithInput(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new InputDataModelDefinitionBuilder(); + setup(builder); + this.Input = builder.Build(); + return this; + } + + /// + public virtual IWorkflowDefinitionBuilder WithOutput(Action setup) + { + ArgumentNullException.ThrowIfNull(setup); + var builder = new OutputDataModelDefinitionBuilder(); + setup(builder); + this.Output = builder.Build(); + return this; + } + /// public virtual IWorkflowDefinitionBuilder UseAuthentication(string name, AuthenticationPolicyDefinition authentication) { diff --git a/src/ServerlessWorkflow.Sdk.IO/ServerlessWorkflow.Sdk.IO.csproj b/src/ServerlessWorkflow.Sdk.IO/ServerlessWorkflow.Sdk.IO.csproj index 0a3d1d1..c1a5989 100644 --- a/src/ServerlessWorkflow.Sdk.IO/ServerlessWorkflow.Sdk.IO.csproj +++ b/src/ServerlessWorkflow.Sdk.IO/ServerlessWorkflow.Sdk.IO.csproj @@ -1,11 +1,10 @@ - net9.0 + net8.0;net9.0 enable enable - 1.0.0 - alpha5.4 + 1.0.1 $(VersionPrefix) $(VersionPrefix) en diff --git a/src/ServerlessWorkflow.Sdk/ContainerCleanupPolicy.cs b/src/ServerlessWorkflow.Sdk/ContainerCleanupPolicy.cs new file mode 100644 index 0000000..46a1283 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/ContainerCleanupPolicy.cs @@ -0,0 +1,46 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk; + +/// +/// Enumerates all supported container cleanup policies +/// +public static class ContainerCleanupPolicy +{ + + /// + /// Indicates that the runtime must delete the container immediately after execution + /// + public const string Always = "always"; + /// + /// Indicates that the runtime must eventually delete the container, after waiting for a specific amount of time. + /// + public const string Eventually = "eventually"; + /// + /// Indicates that the runtime must never delete the container. + /// + public const string Never = "never"; + + /// + /// Gets a new containing all supported values + /// + /// A new containing all supported values + public static IEnumerable AsEnumerable() + { + yield return Always; + yield return Eventually; + yield return Never; + } + +} \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk/EventReadMode.cs b/src/ServerlessWorkflow.Sdk/EventReadMode.cs new file mode 100644 index 0000000..6da631b --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/EventReadMode.cs @@ -0,0 +1,46 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk; + +/// +/// Enumerates all supported event read modes +/// +public static class EventReadMode +{ + + /// + /// Indicates that only the data of consumed events should be read + /// + public const string Data = "data"; + /// + /// Indicates that the whole event envelope should be read, including context attributes + /// + public const string Envelope = "envelope"; + /// + /// Indicates that the event's raw data should be read, without additional transformation (i.e. deserialization) + /// + public const string Raw = "raw"; + + /// + /// Gets a new containing all supported event read modes + /// + /// A new containing all supported event read modes + public static IEnumerable AsEnumerable() + { + yield return Data; + yield return Envelope; + yield return Raw; + } + +} \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk/Models/AsyncApiMessageDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/AsyncApiMessageDefinition.cs new file mode 100644 index 0000000..5a1a91e --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/Models/AsyncApiMessageDefinition.cs @@ -0,0 +1,35 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Models; + +/// +/// Represents the definition of an AsyncAPI message +/// +[DataContract] +public record AsyncApiMessageDefinition +{ + + /// + /// Gets/sets the message's payload, if any + /// + [DataMember(Name = "payload", Order = 1), JsonPropertyName("payload"), JsonPropertyOrder(1), YamlMember(Alias = "payload", Order = 1)] + public virtual object? Payload { get; set; } + + /// + /// Gets/sets the message's headers, if any + /// + [DataMember(Name = "headers", Order = 2), JsonPropertyName("headers"), JsonPropertyOrder(2), YamlMember(Alias = "headers", Order = 2)] + public virtual object? Headers { get; set; } + +} diff --git a/src/ServerlessWorkflow.Sdk/Models/AsyncApiSubscriptionDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/AsyncApiSubscriptionDefinition.cs new file mode 100644 index 0000000..6866115 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/Models/AsyncApiSubscriptionDefinition.cs @@ -0,0 +1,42 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Models; + +/// +/// Represents an object used to configure an AsyncAPI subscription +/// +[DataContract] +public record AsyncApiSubscriptionDefinition +{ + + /// + /// Gets/sets a runtime expression, if any, used to filter consumed messages + /// + [DataMember(Name = "filter", Order = 1), JsonPropertyName("filter"), JsonPropertyOrder(1), YamlMember(Alias = "filter", Order = 1)] + public virtual string? Filter { get; set; } + + /// + /// Gets/sets an object used to configure the subscription's lifetime. + /// + [Required] + [DataMember(Name = "consume", Order = 2), JsonPropertyName("consume"), JsonPropertyOrder(2), YamlMember(Alias = "consume", Order = 2)] + public required virtual AsyncApiSubscriptionLifetimeDefinition Consume { get; set; } + + /// + /// Gets/sets the configuration of the iterator, if any, used to process each consumed message + /// + [DataMember(Name = "foreach", Order = 3), JsonPropertyName("foreach"), JsonPropertyOrder(3), YamlMember(Alias = "foreach", Order = 3)] + public virtual SubscriptionIteratorDefinition? Foreach { get; set; } + +} diff --git a/src/ServerlessWorkflow.Sdk/Models/AsyncApiSubscriptionLifetimeDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/AsyncApiSubscriptionLifetimeDefinition.cs new file mode 100644 index 0000000..62422db --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/Models/AsyncApiSubscriptionLifetimeDefinition.cs @@ -0,0 +1,50 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Models; + +/// +/// Represents an object used to configure the lifetime of an AsyncAPI subscription +/// +[DataContract] +public record AsyncApiSubscriptionLifetimeDefinition +{ + + /// + /// Gets/sets the duration that defines for how long to consume messages + /// /// + [DataMember(Name = "for", Order = 1), JsonPropertyName("for"), JsonPropertyOrder(1), YamlMember(Alias = "for", Order = 1)] + public virtual Duration? For { get; set; } + + /// + /// Gets/sets the amount of messages to consume. + /// Required if and have not been set. + /// /// + [DataMember(Name = "amount", Order = 2), JsonPropertyName("amount"), JsonPropertyOrder(2), YamlMember(Alias = "amount", Order = 2)] + public virtual int? Amount { get; set; } + + /// + /// Gets/sets a runtime expression, if any, used to determine whether or not to keep consuming messages. + /// Required if and have not been set. + /// /// + [DataMember(Name = "while", Order = 3), JsonPropertyName("while"), JsonPropertyOrder(3), YamlMember(Alias = "while", Order = 3)] + public virtual string? While { get; set; } + + /// + /// Gets/sets a runtime expression, if any, used to determine until when to consume messages.. + /// Required if and have not been set. + /// /// + [DataMember(Name = "until", Order = 4), JsonPropertyName("until"), JsonPropertyOrder(4), YamlMember(Alias = "until", Order = 4)] + public virtual string? Until { get; set; } + +} \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk/Models/Tasks/BranchingDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/BranchingDefinition.cs similarity index 97% rename from src/ServerlessWorkflow.Sdk/Models/Tasks/BranchingDefinition.cs rename to src/ServerlessWorkflow.Sdk/Models/BranchingDefinition.cs index b49e1f3..09bd3d0 100644 --- a/src/ServerlessWorkflow.Sdk/Models/Tasks/BranchingDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/BranchingDefinition.cs @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace ServerlessWorkflow.Sdk.Models.Tasks; +namespace ServerlessWorkflow.Sdk.Models; /// /// Represents an object used to configure branches to perform concurrently diff --git a/src/ServerlessWorkflow.Sdk/Models/Calls/AsyncApiCallDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/Calls/AsyncApiCallDefinition.cs index 20e5a80..3ca6c18 100644 --- a/src/ServerlessWorkflow.Sdk/Models/Calls/AsyncApiCallDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/Calls/AsyncApiCallDefinition.cs @@ -29,40 +29,51 @@ public record AsyncApiCallDefinition public required virtual ExternalResourceDefinition Document { get; set; } /// - /// Gets/sets a reference to the AsyncAPI operation to call + /// Gets/sets the name of the channel on which to perform the operation. The operation to perform is defined by declaring either message, in which case the channel's publish operation will be executed, or subscription, in which case the channel's subscribe operation will be executed. + /// Used only in case the referenced document uses AsyncAPI v2.6.0 /// - [Required] - [DataMember(Name = "operationRef", Order = 2), JsonPropertyName("operationRef"), JsonPropertyOrder(2), JsonInclude, YamlMember(Alias = "operationRef", Order = 2)] - public required virtual string OperationRef { get; set; } + [DataMember(Name = "channel", Order = 2), JsonPropertyName("channel"), JsonPropertyOrder(2), JsonInclude, YamlMember(Alias = "channel", Order = 2)] + public virtual string? Channel { get; set; } + + /// + /// Gets/sets a reference to the AsyncAPI operation to call. + /// Used only in case the referenced document uses AsyncAPI v3.0.0. + /// + [DataMember(Name = "operation", Order = 3), JsonPropertyName("operation"), JsonPropertyOrder(3), JsonInclude, YamlMember(Alias = "operation", Order = 3)] + public virtual string? Operation { get; set; } /// - /// Gets/sets a reference to the server to call the specified AsyncAPI operation on. If not set, default to the first server matching the operation's channel. + /// Gets/sets a object used to configure to the server to call the specified AsyncAPI operation on. + /// If not set, default to the first server matching the operation's channel. /// - [DataMember(Name = "server", Order = 3), JsonPropertyName("server"), JsonPropertyOrder(3), JsonInclude, YamlMember(Alias = "server", Order = 3)] + [DataMember(Name = "server", Order = 4), JsonPropertyName("server"), JsonPropertyOrder(4), JsonInclude, YamlMember(Alias = "server", Order = 4)] public virtual string? Server { get; set; } /// - /// Gets/sets the name of the message to use. If not set, defaults to the first message defined by the operation + /// Gets/sets the protocol to use to select the target server. + /// Ignored if has been set. /// - [DataMember(Name = "message", Order = 4), JsonPropertyName("message"), JsonPropertyOrder(4), JsonInclude, YamlMember(Alias = "message", Order = 4)] - public virtual string? Message { get; set; } + [DataMember(Name = "protocol", Order = 5), JsonPropertyName("protocol"), JsonPropertyOrder(5), JsonInclude, YamlMember(Alias = "protocol", Order = 5)] + public virtual string? Protocol { get; set; } /// - /// Gets/sets the name of the binding to use. If not set, defaults to the first binding defined by the operation + /// Gets/sets an object used to configure the message to publish using the target operation. + /// Required if has not been set. /// - [DataMember(Name = "binding", Order = 5), JsonPropertyName("binding"), JsonPropertyOrder(5), JsonInclude, YamlMember(Alias = "binding", Order = 5)] - public virtual string? Binding { get; set; } + [DataMember(Name = "message", Order = 6), JsonPropertyName("message"), JsonPropertyOrder(6), JsonInclude, YamlMember(Alias = "message", Order = 6)] + public virtual AsyncApiMessageDefinition? Message { get; set; } /// - /// Gets/sets the payload to call the AsyncAPI operation with + /// Gets/sets an object used to configure the subscription to messages consumed using the target operation. + /// Required if has not been set. /// - [DataMember(Name = "payload", Order = 6), JsonPropertyName("payload"), JsonPropertyOrder(6), JsonInclude, YamlMember(Alias = "payload", Order = 6)] - public virtual object? Payload { get; set; } + [DataMember(Name = "subscription", Order = 7), JsonPropertyName("subscription"), JsonPropertyOrder(7), JsonInclude, YamlMember(Alias = "subscription", Order = 7)] + public virtual AsyncApiSubscriptionDefinition? Subscription { get; set; } /// /// Gets/sets the authentication policy, if any, to use when calling the AsyncAPI operation /// - [DataMember(Name = "authentication", Order = 7), JsonPropertyName("authentication"), JsonPropertyOrder(7), JsonInclude, YamlMember(Alias = "authentication", Order = 7)] + [DataMember(Name = "authentication", Order = 8), JsonPropertyName("authentication"), JsonPropertyOrder(8), JsonInclude, YamlMember(Alias = "authentication", Order = 8)] public virtual AuthenticationPolicyDefinition? Authentication { get; set; } -} \ No newline at end of file +} diff --git a/src/ServerlessWorkflow.Sdk/Models/Calls/HttpCallDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/Calls/HttpCallDefinition.cs index 82fff94..5fbed16 100644 --- a/src/ServerlessWorkflow.Sdk/Models/Calls/HttpCallDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/Calls/HttpCallDefinition.cs @@ -73,4 +73,12 @@ public virtual Uri EndpointUri [DataMember(Name = "output", Order = 5), JsonPropertyName("output"), JsonPropertyOrder(5), YamlMember(Alias = "output", Order = 5)] public virtual string? Output { get; set; } + /// + /// Gets/sets a boolean indicating whether redirection status codes (300–399) should be treated as errors. + /// If set to 'false', runtimes must raise an error for response status codes outside the 200–299 range. + /// If set to 'true', they must raise an error for status codes outside the 200–399 range. + /// + [DataMember(Name = "redirect", Order = 6), JsonPropertyName("redirect"), JsonPropertyOrder(6), YamlMember(Alias = "redirect", Order = 6)] + public virtual bool Redirect { get; set; } + } \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk/Models/Calls/OpenApiCallDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/Calls/OpenApiCallDefinition.cs index dde27c9..c9699dd 100644 --- a/src/ServerlessWorkflow.Sdk/Models/Calls/OpenApiCallDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/Calls/OpenApiCallDefinition.cs @@ -53,4 +53,12 @@ public record OpenApiCallDefinition [DataMember(Name = "output", Order = 6), JsonPropertyName("output"), JsonPropertyOrder(6), YamlMember(Alias = "output", Order = 6)] public virtual string? Output { get; set; } + /// + /// Gets/sets a boolean indicating whether redirection status codes (300–399) should be treated as errors. + /// If set to 'false', runtimes must raise an error for response status codes outside the 200–299 range. + /// If set to 'true', they must raise an error for status codes outside the 200–399 range. + /// + [DataMember(Name = "redirect", Order = 7), JsonPropertyName("redirect"), JsonPropertyOrder(7), YamlMember(Alias = "redirect", Order = 7)] + public virtual bool Redirect { get; set; } + } diff --git a/src/ServerlessWorkflow.Sdk/Models/EventConsumptionStrategyDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/EventConsumptionStrategyDefinition.cs index 145ebce..5815e91 100644 --- a/src/ServerlessWorkflow.Sdk/Models/EventConsumptionStrategyDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/EventConsumptionStrategyDefinition.cs @@ -27,7 +27,8 @@ public record EventConsumptionStrategyDefinition public virtual EquatableList? All { get; set; } /// - /// Gets/sets a list containing any of the events to consume, if any + /// Gets/sets a list containing any of the events to consume, if any. + /// If empty, listens to all incoming events, and requires to be set. /// [DataMember(Name = "any", Order = 2), JsonPropertyName("any"), JsonPropertyOrder(2), YamlMember(Alias = "any", Order = 2)] public virtual EquatableList? Any { get; set; } @@ -38,4 +39,30 @@ public record EventConsumptionStrategyDefinition [DataMember(Name = "one", Order = 3), JsonPropertyName("one"), JsonPropertyOrder(3), YamlMember(Alias = "one", Order = 3)] public virtual EventFilterDefinition? One { get; set; } + /// + /// Gets/sets the condition or the consumption strategy that defines the events that must be consumed to stop listening + /// + [DataMember(Name = "until", Order = 4), JsonInclude, JsonPropertyName("until"), JsonPropertyOrder(4), YamlMember(Alias = "until", Order = 4)] + protected virtual OneOf? UntilValue { get; set; } + + /// + /// Gets/sets the consumption strategy, if any, that defines the events that must be consumed to stop listening + /// + [IgnoreDataMember, JsonIgnore, YamlIgnore] + public virtual EventConsumptionStrategyDefinition? Until + { + get => this.UntilValue?.T1Value; + set => this.UntilValue = value!; + } + + /// + /// Gets/sets a runtime expression, if any, that represents the condition that must be met to stop listening + /// + [IgnoreDataMember, JsonIgnore, YamlIgnore] + public virtual string? UntilExpression + { + get => this.UntilValue?.T2Value; + set => this.UntilValue = value!; + } + } diff --git a/src/ServerlessWorkflow.Sdk/Models/ForLoopDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/ForLoopDefinition.cs index c82e7b1..f548d8b 100644 --- a/src/ServerlessWorkflow.Sdk/Models/ForLoopDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/ForLoopDefinition.cs @@ -20,7 +20,7 @@ namespace ServerlessWorkflow.Sdk.Models; public record ForLoopDefinition { - /// + /// /// Gets/sets the name of the variable that represents each element in the collection during iteration /// [Required] diff --git a/src/ServerlessWorkflow.Sdk/Models/ListenerDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/ListenerDefinition.cs index d90a198..f1178ad 100644 --- a/src/ServerlessWorkflow.Sdk/Models/ListenerDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/ListenerDefinition.cs @@ -27,4 +27,11 @@ public record ListenerDefinition [DataMember(Name = "to", Order = 1), JsonPropertyName("to"), JsonPropertyOrder(1), YamlMember(Alias = "to", Order = 1)] public required virtual EventConsumptionStrategyDefinition To { get; set; } + /// + /// Gets/sets a string that specifies how events are read during the listen operation + /// See . Defaults to + /// + [DataMember(Name = "read", Order = 1), JsonPropertyName("read"), JsonPropertyOrder(1), YamlMember(Alias = "read", Order = 1)] + public virtual string? Read { get; set; } + } diff --git a/src/ServerlessWorkflow.Sdk/Models/ProcessTypeDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/ProcessTypeDefinition.cs index 56b2c5f..22d6350 100644 --- a/src/ServerlessWorkflow.Sdk/Models/ProcessTypeDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/ProcessTypeDefinition.cs @@ -52,6 +52,14 @@ public record ProcessTypeDefinition [DataMember(Name = "await", Order = 5), JsonPropertyName("await"), JsonPropertyOrder(5), YamlMember(Alias = "await", Order = 5)] public virtual bool? Await { get; set; } + /// + /// Gets/sets the output of the process. + /// See + /// Defaults to + /// + [DataMember(Name = "return", Order = 6), JsonPropertyName("return"), JsonPropertyOrder(6), YamlMember(Alias = "return", Order = 6)] + public virtual string? Return { get; set; } + /// /// Gets the type of the defined process tasks /// diff --git a/src/ServerlessWorkflow.Sdk/Models/Processes/ContainerLifetimeDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/Processes/ContainerLifetimeDefinition.cs new file mode 100644 index 0000000..e399891 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/Models/Processes/ContainerLifetimeDefinition.cs @@ -0,0 +1,38 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Models.Processes; + +/// +/// Represents an object used to configure the lifetime of a container +/// +[DataContract] +public record ContainerLifetimeDefinition +{ + + /// + /// Gets/sets the cleanup policy to use. + /// See + /// Defaults to + /// + [Required, MinLength(1)] + [DataMember(Name = "cleanup", Order = 1), JsonPropertyName("cleanup"), JsonPropertyOrder(1), YamlMember(Alias = "cleanup", Order = 1)] + public required virtual string Cleanup { get; set; } + + /// + /// Gets/sets the duration, if any, after which to delete the container once executed. + /// Required if has been set to , otherwise ignored. + /// + [DataMember(Name = "duration", Order = 2), JsonPropertyName("duration"), JsonPropertyOrder(2), YamlMember(Alias = "duration", Order = 2)] + public virtual Duration? Duration { get; set; } +} diff --git a/src/ServerlessWorkflow.Sdk/Models/Processes/ContainerProcessDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/Processes/ContainerProcessDefinition.cs index c17af67..d235097 100644 --- a/src/ServerlessWorkflow.Sdk/Models/Processes/ContainerProcessDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/Processes/ContainerProcessDefinition.cs @@ -26,30 +26,42 @@ public record ContainerProcessDefinition /// [Required, MinLength(1)] [DataMember(Name = "image", Order = 1), JsonPropertyName("image"), JsonPropertyOrder(1), YamlMember(Alias = "image", Order = 1)] - public required virtual string Image { get; set; } = null!; + public required virtual string Image { get; set; } + + /// + /// Gets/sets a runtime expression, if any, used to give specific name to the container + /// + [DataMember(Name = "name", Order = 2), JsonPropertyName("name"), JsonPropertyOrder(2), YamlMember(Alias = "name", Order = 2)] + public virtual string? Name { get; set; } /// /// Gets/sets the command, if any, to execute on the container /// - [DataMember(Name = "command", Order = 2), JsonPropertyName("command"), JsonPropertyOrder(2), YamlMember(Alias = "command", Order = 2)] + [DataMember(Name = "command", Order = 3), JsonPropertyName("command"), JsonPropertyOrder(3), YamlMember(Alias = "command", Order = 3)] public virtual string? Command { get; set; } /// /// Gets/sets a list containing the container's port mappings, if any /// - [DataMember(Name = "ports", Order = 3), JsonPropertyName("ports"), JsonPropertyOrder(3), YamlMember(Alias = "ports", Order = 3)] + [DataMember(Name = "ports", Order = 4), JsonPropertyName("ports"), JsonPropertyOrder(4), YamlMember(Alias = "ports", Order = 4)] public virtual EquatableDictionary? Ports { get; set; } /// /// Gets/sets the volume mapping for the container, if any /// - [DataMember(Name = "volumes", Order = 4), JsonPropertyName("volumes"), JsonPropertyOrder(4), YamlMember(Alias = "volumes", Order = 4)] + [DataMember(Name = "volumes", Order = 5), JsonPropertyName("volumes"), JsonPropertyOrder(5), YamlMember(Alias = "volumes", Order = 5)] public virtual EquatableDictionary? Volumes { get; set; } /// /// Gets/sets a key/value mapping of the environment variables, if any, to use when running the configured process /// - [DataMember(Name = "environment", Order = 5), JsonPropertyName("environment"), JsonPropertyOrder(5), YamlMember(Alias = "environment", Order = 5)] + [DataMember(Name = "environment", Order = 6), JsonPropertyName("environment"), JsonPropertyOrder(6), YamlMember(Alias = "environment", Order = 6)] public virtual EquatableDictionary? Environment { get; set; } + /// + /// Gets/sets an object object used to configure the container's lifetime + /// + [DataMember(Name = "lifetime", Order = 7), JsonPropertyName("lifetime"), JsonPropertyOrder(7), YamlMember(Alias = "lifetime", Order = 7)] + public virtual ContainerLifetimeDefinition? Lifetime { get; set; } + } diff --git a/src/ServerlessWorkflow.Sdk/Models/RaiseErrorDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/RaiseErrorDefinition.cs index 825e18c..7a38ef4 100644 --- a/src/ServerlessWorkflow.Sdk/Models/RaiseErrorDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/RaiseErrorDefinition.cs @@ -49,7 +49,7 @@ public virtual string? ErrorReference } /// - /// Gets/sets the endpoint at which to get the defined resource + /// Gets/sets the error to raise /// [Required] [DataMember(Name = "error", Order = 1), JsonInclude, JsonPropertyName("error"), JsonPropertyOrder(1), YamlMember(Alias = "error", Order = 1)] diff --git a/src/ServerlessWorkflow.Sdk/Models/SubscriptionIteratorDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/SubscriptionIteratorDefinition.cs new file mode 100644 index 0000000..0c4b7f9 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/Models/SubscriptionIteratorDefinition.cs @@ -0,0 +1,55 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk.Models; + +/// +/// Represents the definition of a subscription iterator, used to configure the processing of each event or message consumed by a subscription +/// +[DataContract] +public record SubscriptionIteratorDefinition +{ + + /// + /// Gets/sets the name of the variable used to store the item being enumerated. + /// Defaults to `item` + /// + [DataMember(Name = "item", Order = 1), JsonPropertyName("item"), JsonPropertyOrder(1), YamlMember(Alias = "item", Order = 1)] + public virtual string? Item { get; set; } + + /// + /// Gets/sets the name of the variable used to store the index of the item being enumerates + /// Defaults to `index` + /// + [DataMember(Name = "at", Order = 2), JsonPropertyName("at"), JsonPropertyOrder(2), YamlMember(Alias = "at", Order = 2)] + public virtual string? At { get; set; } + + /// + /// Gets/sets the tasks to run for each consumed event or message + /// + [DataMember(Name = "do", Order = 3), JsonPropertyName("do"), JsonPropertyOrder(3), YamlMember(Alias = "do", Order = 3)] + public virtual Map? Do { get; set; } + + /// + /// Gets/sets the definition, if any, of the data to output for each iteration + /// + [DataMember(Name = "output", Order = 4), JsonPropertyName("output"), JsonPropertyOrder(4), YamlMember(Alias = "output", Order = 4)] + public virtual OutputDataModelDefinition? Output { get; set; } + + /// + /// Gets/sets the definition, if any, of the data to export for each iteration + /// + [DataMember(Name = "export", Order = 5), JsonPropertyName("export"), JsonPropertyOrder(5), YamlMember(Alias = "export", Order = 5)] + public virtual OutputDataModelDefinition? Export { get; set; } + +} \ No newline at end of file diff --git a/src/ServerlessWorkflow.Sdk/Models/Tasks/ListenTaskDefinition.cs b/src/ServerlessWorkflow.Sdk/Models/Tasks/ListenTaskDefinition.cs index 96fabd8..88bc273 100644 --- a/src/ServerlessWorkflow.Sdk/Models/Tasks/ListenTaskDefinition.cs +++ b/src/ServerlessWorkflow.Sdk/Models/Tasks/ListenTaskDefinition.cs @@ -32,4 +32,10 @@ public record ListenTaskDefinition [DataMember(Name = "listen", Order = 1), JsonPropertyName("listen"), JsonPropertyOrder(1), YamlMember(Alias = "listen", Order = 1)] public required virtual ListenerDefinition Listen { get; set; } + /// + /// Gets/sets the configuration of the iterator, if any, used to process each consumed event + /// + [DataMember(Name = "foreach", Order = 2), JsonPropertyName("foreach"), JsonPropertyOrder(2), YamlMember(Alias = "foreach", Order = 2)] + public virtual SubscriptionIteratorDefinition? Foreach { get; set; } + } diff --git a/src/ServerlessWorkflow.Sdk/ProcessReturnType.cs b/src/ServerlessWorkflow.Sdk/ProcessReturnType.cs new file mode 100644 index 0000000..591bcc6 --- /dev/null +++ b/src/ServerlessWorkflow.Sdk/ProcessReturnType.cs @@ -0,0 +1,56 @@ +// Copyright © 2024-Present The Serverless Workflow Specification Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"), +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace ServerlessWorkflow.Sdk; + +/// +/// Enumerates all supported process return types +/// +public static class ProcessReturnType +{ + + /// + /// Indicates that the process must return only the content of its Standard Output (STDOUT) stream + /// + public const string Stdout = "stdout"; + /// + /// Indicates that the process must return only the content of its Standard Error (STDERR) stream + /// + public const string Stderr = "stderr"; + /// + /// Indicates that the process must return only its exit code + /// + public const string Code = "code"; + /// + /// Indicates that the process must return an object that wraps the content of its STDOUT stream, the content of its STDERR stream and its exit code + /// + public const string All = "all"; + /// + /// Indicates that the process must not return anything + /// + public const string None = "none"; + + /// + /// Gets a new containing all supported values + /// + /// A new containing all supported values + public static IEnumerable AsEnumerable() + { + yield return Stdout; + yield return Stderr; + yield return Code; + yield return All; + yield return None; + } + +} diff --git a/src/ServerlessWorkflow.Sdk/RuntimeExpressions.cs b/src/ServerlessWorkflow.Sdk/RuntimeExpressions.cs index a6e9436..138afa9 100644 --- a/src/ServerlessWorkflow.Sdk/RuntimeExpressions.cs +++ b/src/ServerlessWorkflow.Sdk/RuntimeExpressions.cs @@ -82,6 +82,29 @@ public static class Arguments /// Gets the name of the 'error' argument, used to access the current error, if any /// public const string Error = "error"; + /// + /// Gets the name of the 'authorization' argument, used to access a task's resolved authorization + /// + public const string Authorization = "authorization"; + + /// + /// Gets an that contains all supported runtime expression arguments + /// + /// A new that contains all supported runtime expression arguments + public static IEnumerable AsEnumerable() + { + yield return Runtime; + yield return Workflow; + yield return Context; + yield return Each; + yield return Index; + yield return Output; + yield return Secret; + yield return Task; + yield return Input; + yield return Error; + yield return Authorization; + } } diff --git a/src/ServerlessWorkflow.Sdk/ServerlessWorkflow.Sdk.csproj b/src/ServerlessWorkflow.Sdk/ServerlessWorkflow.Sdk.csproj index 565bd8e..d01894f 100644 --- a/src/ServerlessWorkflow.Sdk/ServerlessWorkflow.Sdk.csproj +++ b/src/ServerlessWorkflow.Sdk/ServerlessWorkflow.Sdk.csproj @@ -1,11 +1,10 @@ - net9.0 + net8.0;net9.0 enable enable - 1.0.0 - alpha5.4 + 1.0.1 $(VersionPrefix) $(VersionPrefix) en @@ -33,11 +32,11 @@ - - - - - + + + + + diff --git a/tests/ServerlessWorkflow.Sdk.UnitTests/ServerlessWorkflow.Sdk.UnitTests.csproj b/tests/ServerlessWorkflow.Sdk.UnitTests/ServerlessWorkflow.Sdk.UnitTests.csproj index 37ede5e..cb47d09 100644 --- a/tests/ServerlessWorkflow.Sdk.UnitTests/ServerlessWorkflow.Sdk.UnitTests.csproj +++ b/tests/ServerlessWorkflow.Sdk.UnitTests/ServerlessWorkflow.Sdk.UnitTests.csproj @@ -1,7 +1,7 @@ - net9.0 + net8.0;net9.0 enable enable @@ -10,14 +10,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive