Skip to content

Commit d29c919

Browse files
committed
fix(SDK): Added a new IScheduleBuilder fluent builder service used to build and configure a workflow's start schedule
Closes #42
1 parent f5754af commit d29c919

File tree

9 files changed

+340
-8
lines changed

9 files changed

+340
-8
lines changed

src/ServerlessWorkflow.Sdk.UnitTests/Cases/Services/WorkflowBuilderTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*
1616
*/
17+
using Cronos;
1718
using Newtonsoft.Json.Linq;
1819
using ServerlessWorkflow.Sdk.Models;
1920
using ServerlessWorkflow.Sdk.Services.FluentBuilders;
@@ -47,10 +48,9 @@ public void Build()
4748
strat.WithName("retry1")
4849
.WithNoDelay()
4950
.MaxAttempts(5))
50-
.StartsWith(flow =>
51-
flow.Delay(TimeSpan.FromSeconds(3)))
52-
.Then(flow =>
53-
flow.Inject(new JObject()))
51+
.StartsWith(flow => flow.Delay(TimeSpan.FromSeconds(3)),
52+
schedule => schedule.Every("0 * * * *"))
53+
.Then(flow => flow.Inject(new JObject()))
5454
.Then(flow =>
5555
flow.Execute(action =>
5656
action.Invoke(function =>

src/ServerlessWorkflow.Sdk/Cron.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2021-Present The Serverless Workflow Specification Authors
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
using Cronos;
19+
20+
namespace ServerlessWorkflow.Sdk
21+
{
22+
23+
/// <summary>
24+
/// Defines helper methods to handle CRON expressions
25+
/// </summary>
26+
public static class Cron
27+
{
28+
29+
/// <summary>
30+
/// Parses the specified input into a new <see cref="CronExpression"/>
31+
/// </summary>
32+
/// <param name="input">The input to parse</param>
33+
/// <returns>A new <see cref="CronExpression"/></returns>
34+
public static CronExpression Parse(string input) => CronExpression.Parse(input);
35+
36+
/// <summary>
37+
/// Parses the specified input into a new <see cref="CronExpression"/>
38+
/// </summary>
39+
/// <param name="input">The input to parse</param>
40+
/// <param name="cron">The parsed <see cref="CronExpression"/>, if any</param>
41+
/// <returns>A boolean indicating whether or not the specified input could be parsed</returns>
42+
public static bool TryParse(string input, out CronExpression? cron)
43+
{
44+
cron = default;
45+
try
46+
{
47+
cron = Parse(input);
48+
return true;
49+
}
50+
catch
51+
{
52+
return false;
53+
}
54+
}
55+
56+
}
57+
58+
}

src/ServerlessWorkflow.Sdk/Models/ScheduleDefinition.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*
1616
*/
1717
using Newtonsoft.Json.Linq;
18+
using System;
1819
using YamlDotNet.Serialization;
1920

2021
namespace ServerlessWorkflow.Sdk.Models
@@ -31,9 +32,11 @@ public class ScheduleDefinition
3132
/// <summary>
3233
/// Gets/sets the time interval (ISO 8601 format) describing when workflow instances can be created.
3334
/// </summary>
35+
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.Iso8601TimeSpanConverter))]
36+
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.Converters.Iso8601NullableTimeSpanConverter))]
3437
[ProtoMember(1)]
3538
[DataMember(Order = 1)]
36-
public virtual string? Interval { get; set; }
39+
public virtual TimeSpan? Interval { get; set; }
3740

3841
/// <summary>
3942
/// Gets/sets a <see cref="JToken"/> that represents the CRON expression that defines when the workflow instance should be created

src/ServerlessWorkflow.Sdk/ServerlessWorkflow.Sdk.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
<TargetFramework>net6.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<NeutralLanguage>en</NeutralLanguage>
7-
<AssemblyVersion>0.8.1.16</AssemblyVersion>
8-
<FileVersion>0.8.1.16</FileVersion>
9-
<Version>0.8.1.16</Version>
7+
<AssemblyVersion>0.8.2</AssemblyVersion>
8+
<FileVersion>0.8.2</FileVersion>
9+
<Version>0.8.2</Version>
1010
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
1111
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
1212
<PackageLicenseFile>LICENSE</PackageLicenseFile>
@@ -44,6 +44,7 @@
4444

4545
<ItemGroup>
4646
<PackageReference Include="CloudNative.CloudEvents" Version="2.3.1" />
47+
<PackageReference Include="Cronos" Version="0.7.1" />
4748
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.2.1" />
4849
<PackageReference Include="Iso8601DurationHelper" Version="1.0.5" />
4950
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />

src/ServerlessWorkflow.Sdk/ServerlessWorkflow.Sdk.xml

Lines changed: 98 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2021-Present The Serverless Workflow Specification Authors
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
using ServerlessWorkflow.Sdk.Models;
18+
using System;
19+
20+
namespace ServerlessWorkflow.Sdk.Services.FluentBuilders
21+
{
22+
23+
/// <summary>
24+
/// Defines the fundamentals of a service used to build a <see cref="ScheduleDefinition"/>
25+
/// </summary>
26+
public interface IScheduleBuilder
27+
{
28+
29+
/// <summary>
30+
/// Configures the <see cref="ScheduleDefinition"/> to execute at the specified interval
31+
/// </summary>
32+
/// <param name="interval">The interval at which to execute the <see cref="ScheduleDefinition"/></param>
33+
/// <returns>The configured <see cref="IScheduleBuilder"/></returns>
34+
IScheduleBuilder AtInterval(TimeSpan interval);
35+
36+
/// <summary>
37+
/// Configures the <see cref="ScheduleDefinition"/> to execute at a frequency defined by the specified CRON expression
38+
/// </summary>
39+
/// <param name="cronExpression">A CRON expression that defines the frequency at which to execute the <see cref="ScheduleDefinition"/></param>
40+
/// <param name="validUntil">The date and time when the cron expression invocation is no longer valid</param>
41+
/// <returns>The configured <see cref="IScheduleBuilder"/></returns>
42+
IScheduleBuilder Every(string cronExpression, DateTime? validUntil = null);
43+
44+
/// <summary>
45+
/// Configures the <see cref="ScheduleDefinition"/> to use the specified timezone
46+
/// </summary>
47+
/// <param name="timezone">The timezone to use</param>
48+
/// <returns>The configured <see cref="IScheduleBuilder"/></returns>
49+
IScheduleBuilder UseTimezone(string? timezone);
50+
51+
/// <summary>
52+
/// Builds a new <see cref="ScheduleDefinition"/>
53+
/// </summary>
54+
/// <returns>A new <see cref="ScheduleDefinition"/></returns>
55+
ScheduleDefinition Build();
56+
57+
}
58+
59+
}

src/ServerlessWorkflow.Sdk/Services/FluentBuilders/Interfaces/IWorkflowBuilder.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,23 @@ public interface IWorkflowBuilder
215215
/// <returns>A new <see cref="IPipelineBuilder"/> used to configure the <see cref="WorkflowDefinition"/>'s <see cref="StateDefinition"/>s</returns>
216216
IPipelineBuilder StartsWith(string name, Func<IStateBuilderFactory, IStateBuilder> stateSetup);
217217

218+
/// <summary>
219+
/// Sets and configures the startup <see cref="StateDefinition"/>
220+
/// </summary>
221+
/// <param name="stateSetup">An <see cref="Func{T, TResult}"/> used to setup the startup <see cref="StateDefinition"/></param>
222+
/// <param name="scheduleSetup">An <see cref="Action{T}"/> used to setup the <see cref="WorkflowDefinition"/>'s schedule</param>
223+
/// <returns>A new <see cref="IPipelineBuilder"/> used to configure the <see cref="WorkflowDefinition"/>'s <see cref="StateDefinition"/>s</returns>
224+
IPipelineBuilder StartsWith(Func<IStateBuilderFactory, IStateBuilder> stateSetup, Action<IScheduleBuilder> scheduleSetup);
225+
226+
/// <summary>
227+
/// Sets and configures the startup <see cref="StateDefinition"/>
228+
/// </summary>
229+
/// <param name="name">The name of the startup <see cref="StateDefinition"/></param>
230+
/// <param name="stateSetup">An <see cref="Func{T, TResult}"/> used to setup the startup <see cref="StateDefinition"/></param>
231+
/// <param name="scheduleSetup">An <see cref="Action{T}"/> used to setup the <see cref="WorkflowDefinition"/>'s schedule</param>
232+
/// <returns>A new <see cref="IPipelineBuilder"/> used to configure the <see cref="WorkflowDefinition"/>'s <see cref="StateDefinition"/>s</returns>
233+
IPipelineBuilder StartsWith(string name, Func<IStateBuilderFactory, IStateBuilder> stateSetup, Action<IScheduleBuilder> scheduleSetup);
234+
218235
/// <summary>
219236
/// Adds the <see cref="EventDefinition"/>s defined in the specified file
220237
/// </summary>

0 commit comments

Comments
 (0)