Skip to content

Commit 9cc065a

Browse files
committed
Initial commit
1 parent c1f49b8 commit 9cc065a

File tree

368 files changed

+9786
-262
lines changed

Some content is hidden

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

368 files changed

+9786
-262
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using ServerlessWorkflow.Sdk.Serialization;
2+
3+
namespace ServerlessWorkflow.Sdk.UnitTests.Cases.Serialization;
4+
5+
public class JsonSerializationTests
6+
: SerializationTestsBase
7+
{
8+
9+
protected override T Deserialize<T>(string input) => Serializer.Json.Deserialize<T>(input)!;
10+
11+
protected override string Serialize<T>(T graph) => Serializer.Json.Serialize(graph);
12+
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using ServerlessWorkflow.Sdk.Serialization;
2+
3+
namespace ServerlessWorkflow.Sdk.UnitTests.Cases.Serialization;
4+
5+
public class YamlSerializationTests
6+
: SerializationTestsBase
7+
{
8+
9+
protected override T Deserialize<T>(string input) => Serializer.Yaml.Deserialize<T>(input)!;
10+
11+
protected override string Serialize<T>(T graph) => Serializer.Yaml.Serialize(graph);
12+
13+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
namespace ServerlessWorkflow.Sdk.UnitTests.Cases;
2+
3+
public abstract class SerializationTestsBase
4+
{
5+
6+
protected abstract string Serialize<T>(T graph);
7+
8+
protected abstract T Deserialize<T>(string input);
9+
10+
[Fact]
11+
public void Serialize_And_Deserialize_WorkflowDefinition_Should_Work()
12+
{
13+
//arrange
14+
var toSerialize = WorkflowDefinitionFactory.Create();
15+
16+
//act
17+
var text = Serialize(toSerialize);
18+
var deserialized = Deserialize<WorkflowDefinition>(text);
19+
20+
//assert
21+
deserialized.Should().BeEquivalentTo(toSerialize);
22+
}
23+
24+
[Fact]
25+
public void Serialize_And_Deserialize_CallbackState_Should_Work()
26+
{
27+
28+
}
29+
30+
[Fact]
31+
public void Serialize_And_Deserialize_EventState_Should_Work()
32+
{
33+
34+
}
35+
36+
[Fact]
37+
public void Serialize_And_Deserialize_ExtensionState_Should_Work()
38+
{
39+
40+
}
41+
42+
[Fact]
43+
public void Serialize_And_Deserialize_ForEachState_Should_Work()
44+
{
45+
46+
}
47+
48+
[Fact]
49+
public void Serialize_And_Deserialize_InjectState_Should_Work()
50+
{
51+
52+
}
53+
54+
[Fact]
55+
public void Serialize_And_Deserialize_OperationState_Should_Work()
56+
{
57+
58+
}
59+
60+
[Fact]
61+
public void Serialize_And_Deserialize_ParallelState_Should_Work()
62+
{
63+
64+
}
65+
66+
[Fact]
67+
public void Serialize_And_Deserialize_SleepState_Should_Work()
68+
{
69+
70+
}
71+
72+
[Fact]
73+
public void Serialize_And_Deserialize_SwitchState_Should_Work()
74+
{
75+
76+
}
77+
78+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net7.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="FluentAssertions" Version="6.9.0" />
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
14+
<PackageReference Include="xunit" Version="2.4.2" />
15+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
16+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
17+
<PrivateAssets>all</PrivateAssets>
18+
</PackageReference>
19+
<PackageReference Include="coverlet.collector" Version="3.1.2">
20+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
21+
<PrivateAssets>all</PrivateAssets>
22+
</PackageReference>
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<ProjectReference Include="..\ServerlessWorkflow.Sdk\ServerlessWorkflow.Sdk.csproj" />
27+
</ItemGroup>
28+
29+
</Project>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using ServerlessWorkflow.Sdk.Services.FluentBuilders;
2+
using System.Collections;
3+
4+
namespace ServerlessWorkflow.Sdk.UnitTests.Services;
5+
6+
public static class WorkflowDefinitionFactory
7+
{
8+
9+
public static WorkflowDefinition Create()
10+
{
11+
return new WorkflowBuilder()
12+
.WithId("fake")
13+
.WithName("Fake Workflow")
14+
.WithDescription("Fake Workflow Description")
15+
.WithSpecVersion(ServerlessWorkflowSpecVersion.Latest)
16+
.WithVersion("1.0.0")
17+
.WithAnnotation("fake-annotation: Fake value")
18+
.WithDataInputSchema(new Uri("https://tests.serverlessworkflow.io"))
19+
.WithMetadata(new Dictionary<string, object>() { { "fakeMetadataKey", "fakeMetadataValue" } })
20+
.WithExecutionTimeout(time => time.Run("fake-workflow:1.0.1").After(TimeSpan.FromSeconds(30)))
21+
.AddBasicAuthentication("fake-auth-basic", basic => basic.WithUserName("fake@email.com").WithPassword("0123456789"))
22+
.AddBearerAuthentication("fake-auth-bearer", bearer => bearer.WithToken("fake-token"))
23+
.AddOAuth2Authentication("fake-auth-oauth2", oauth2 => oauth2.UseGrantType(OAuth2GrantType.ClientCredentials).WithClientId("fake-client").WithPassword("fake-password"))
24+
.AddConstant("fake-constant", "fakeValue")
25+
.AddEvent(e => e.WithName("fake-event-consumed").WithSource(new Uri("https://tests.serverlessworkflow.io")).WithType("tests.serverlessworkflow.io").CorrelateUsing("subject").IsConsumed())
26+
.AddEvent(e => e.WithName("fake-event-produced").WithSource(new Uri("https://tests.serverlessworkflow.io")).WithType("tests.serverlessworkflow.io").CorrelateUsing("subject").IsProduced())
27+
.AddFunction(f => f.WithName("fake-function-asyncapi").UseAuthentication("fake-auth-basic").OfType(FunctionType.AsyncApi).ForOperation(new Uri("https://tests.serverlessworkflow.io#fakeOperationId")))
28+
.AddFunction(f => f.WithName("fake-function-expression").UseAuthentication("fake-auth-bearer").OfType(FunctionType.Expression).ForOperation("${ . }"))
29+
.AddFunction(f => f.WithName("fake-function-graphql").UseAuthentication("fake-auth-oauth2").OfType(FunctionType.GraphQL).ForOperation(new Uri("https://tests.serverlessworkflow.io#fakeOperationId")))
30+
.AddFunction(f => f.WithName("fake-function-odata").UseAuthentication("fake-auth-basic").OfType(FunctionType.OData).ForOperation(new Uri("https://tests.serverlessworkflow.io#fakeOperationId")))
31+
.AddFunction(f => f.WithName("fake-function-rest").UseAuthentication("fake-auth-bearer").OfType(FunctionType.Rest).ForOperation(new Uri("https://tests.serverlessworkflow.io#fakeOperationId")))
32+
.AddFunction(f => f.WithName("fake-function-rpc").UseAuthentication("fake-auth-oauth2").OfType(FunctionType.Rpc).ForOperation(new Uri("https://tests.serverlessworkflow.io#fakeOperationId")))
33+
.AddRetryStrategy(retry => retry.WithName("fakeRetry").WithDelayOf(TimeSpan.FromSeconds(2)).WithMaxDelay(TimeSpan.FromSeconds(10)).MaxAttempts(3))
34+
.AddSecret("fake-secret")
35+
.UseJq()
36+
.StartsWith("fake-inject", state => state.Inject(new { foo = "bar" }))
37+
.Then("fake-operation", state => state.Execute("fake-function-asyncapi", action => action.Invoke("fake-function-asyncapi").Invoke("fake-function-rest").WithArguments(new Dictionary<string, string>() { { "fake-argument-1", "fake-argument-1-value" }, { "fake-argument-2", "fake-argument-2-value" } })))
38+
.End()
39+
.Build();
40+
}
41+
42+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
global using FluentAssertions;
2+
global using ServerlessWorkflow.Sdk.Models;
3+
global using ServerlessWorkflow.Sdk.Services.FluentBuilders;
4+
global using ServerlessWorkflow.Sdk.UnitTests.Services;
5+
global using Xunit;

ServerlessWorkflow.Sdk.sln

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerlessWorkflow.Sdk.UnitTests.bck", "src\ServerlessWorkflow.Sdk.UnitTests\ServerlessWorkflow.Sdk.UnitTests.bck.csproj", "{70AD35E0-0C14-4EBF-A841-B0D084392753}"
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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerlessWorkflow.Sdk", "ServerlessWorkflow.Sdk\ServerlessWorkflow.Sdk.csproj", "{64E2DFCE-53F8-4269-A338-51F66F82D815}"
9+
EndProject
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerlessWorkflow.Sdk.bck", "src\ServerlessWorkflow.Sdk.Bck\ServerlessWorkflow.Sdk.bck.csproj", "{1A04902E-047C-4153-85B4-CDD52C44A343}"
11+
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerlessWorkflow.Sdk.UnitTests", "ServerlessWorkflow.Sdk.UnitTests\ServerlessWorkflow.Sdk.UnitTests.csproj", "{E3301336-7A08-4FF1-9A9F-E4153F74C70A}"
913
EndProject
1014
Global
1115
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1216
Debug|Any CPU = Debug|Any CPU
1317
Release|Any CPU = Release|Any CPU
1418
EndGlobalSection
1519
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
2020
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2121
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Debug|Any CPU.Build.0 = Debug|Any CPU
2222
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Release|Any CPU.ActiveCfg = Release|Any CPU
2323
{70AD35E0-0C14-4EBF-A841-B0D084392753}.Release|Any CPU.Build.0 = Release|Any CPU
24+
{64E2DFCE-53F8-4269-A338-51F66F82D815}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25+
{64E2DFCE-53F8-4269-A338-51F66F82D815}.Debug|Any CPU.Build.0 = Debug|Any CPU
26+
{64E2DFCE-53F8-4269-A338-51F66F82D815}.Release|Any CPU.ActiveCfg = Release|Any CPU
27+
{64E2DFCE-53F8-4269-A338-51F66F82D815}.Release|Any CPU.Build.0 = Release|Any CPU
28+
{1A04902E-047C-4153-85B4-CDD52C44A343}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29+
{1A04902E-047C-4153-85B4-CDD52C44A343}.Debug|Any CPU.Build.0 = Debug|Any CPU
30+
{1A04902E-047C-4153-85B4-CDD52C44A343}.Release|Any CPU.ActiveCfg = Release|Any CPU
31+
{1A04902E-047C-4153-85B4-CDD52C44A343}.Release|Any CPU.Build.0 = Release|Any CPU
32+
{E3301336-7A08-4FF1-9A9F-E4153F74C70A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33+
{E3301336-7A08-4FF1-9A9F-E4153F74C70A}.Debug|Any CPU.Build.0 = Debug|Any CPU
34+
{E3301336-7A08-4FF1-9A9F-E4153F74C70A}.Release|Any CPU.ActiveCfg = Release|Any CPU
35+
{E3301336-7A08-4FF1-9A9F-E4153F74C70A}.Release|Any CPU.Build.0 = Release|Any CPU
2436
EndGlobalSection
2537
GlobalSection(SolutionProperties) = preSolution
2638
HideSolutionNode = FALSE
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace ServerlessWorkflow.Sdk;
2+
3+
/// <summary>
4+
/// Enumerates all types of actions
5+
/// </summary>
6+
public static class ActionExecutionMode
7+
{
8+
9+
/// <summary>
10+
/// Indicates a sequential execution of actions
11+
/// </summary>
12+
public const string Sequential = "sequential";
13+
14+
/// <summary>
15+
/// Indicates a parallel execution of actions
16+
/// </summary>
17+
public const string Parallel = "parallel";
18+
19+
}

ServerlessWorkflow.Sdk/ActionType.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace ServerlessWorkflow.Sdk;
2+
3+
/// <summary>
4+
/// Enumerates all types of actions
5+
/// </summary>
6+
public static class ActionType
7+
{
8+
9+
/// <summary>
10+
/// Indicates an action that invokes a function
11+
/// </summary>
12+
public const string Function = "function";
13+
14+
/// <summary>
15+
/// Indicates an action that executes a cloud event trigger
16+
/// </summary>
17+
public const string Trigger = "trigger";
18+
19+
/// <summary>
20+
/// Indicates an action that executes a subflow
21+
/// </summary>
22+
public const string Subflow = "subflow";
23+
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace ServerlessWorkflow.Sdk;
2+
3+
/// <summary>
4+
/// Enumerates all supported authentication schemes
5+
/// </summary>
6+
public static class AuthenticationScheme
7+
{
8+
9+
/// <summary>
10+
/// Gets the 'basic' authentication scheme
11+
/// </summary>
12+
public const string Basic = "basic";
13+
/// <summary>
14+
/// Gets the 'bearer' authentication scheme
15+
/// </summary>
16+
public const string Bearer = "bearer";
17+
/// <summary>
18+
/// Gets the 'oauth2' authentication scheme
19+
/// </summary>
20+
public const string OAuth2 = "oauth2";
21+
22+
}

ServerlessWorkflow.Sdk/Cron.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using Cronos;
2+
3+
namespace ServerlessWorkflow.Sdk;
4+
5+
/// <summary>
6+
/// Defines helper methods to handle CRON expressions
7+
/// </summary>
8+
public static class Cron
9+
{
10+
11+
/// <summary>
12+
/// Parses the specified input into a new <see cref="CronExpression"/>
13+
/// </summary>
14+
/// <param name="input">The input to parse</param>
15+
/// <returns>A new <see cref="CronExpression"/></returns>
16+
public static CronExpression Parse(string input) => CronExpression.Parse(input);
17+
18+
/// <summary>
19+
/// Parses the specified input into a new <see cref="CronExpression"/>
20+
/// </summary>
21+
/// <param name="input">The input to parse</param>
22+
/// <param name="cron">The parsed <see cref="CronExpression"/>, if any</param>
23+
/// <returns>A boolean indicating whether or not the specified input could be parsed</returns>
24+
public static bool TryParse(string input, out CronExpression? cron)
25+
{
26+
cron = default;
27+
try
28+
{
29+
cron = Parse(input);
30+
return true;
31+
}
32+
catch
33+
{
34+
return false;
35+
}
36+
}
37+
38+
}

ServerlessWorkflow.Sdk/EventKind.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace ServerlessWorkflow.Sdk;
2+
3+
/// <summary>
4+
/// Enumerates all kinds of workflow events
5+
/// </summary>
6+
public static class EventKind
7+
{
8+
9+
/// <summary>
10+
/// Indicates an event to consume
11+
/// </summary>
12+
public const string Consumed = "consumed";
13+
14+
/// <summary>
15+
/// Indicates an event to produce
16+
/// </summary>
17+
public const string Produced = "produced";
18+
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace ServerlessWorkflow.Sdk;
2+
3+
/// <summary>
4+
/// Defines extensions for Iso8601DurationHelper.Durations
5+
/// </summary>
6+
public static class DurationExtensions
7+
{
8+
9+
/// <summary>
10+
/// Converts the <see cref="Iso8601DurationHelper.Duration"/> into a <see cref="TimeSpan"/>
11+
/// </summary>
12+
/// <param name="duration">The <see cref="Iso8601DurationHelper.Duration"/> to convert</param>
13+
/// <returns>The converted <see cref="TimeSpan"/></returns>
14+
public static TimeSpan ToTimeSpan(this Iso8601DurationHelper.Duration duration)
15+
{
16+
return new TimeSpan((int)(duration.Days + duration.Weeks * 7 + duration.Months * 30 + duration.Years * 365), (int)duration.Hours, (int)duration.Minutes, (int)duration.Seconds);
17+
}
18+
19+
}

0 commit comments

Comments
 (0)