Implemented Cron activity (#23)
This commit is contained in:
parent
d957d67d9b
commit
a167799cd6
21
Elsa.sln
21
Elsa.sln
|
|
@ -67,6 +67,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Email", "sr
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Web.Activities.Email", "src\web\modules\Elsa.Web.Activities.Email\Elsa.Web.Activities.Email.csproj", "{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Cron", "src\activities\Elsa.Activities.Cron\Elsa.Activities.Cron.csproj", "{E4B71DC4-3E73-49C3-9B4E-CA13909F222D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Web.Activities.Cron", "src\web\modules\Elsa.Web.Activities.Cron\Elsa.Web.Activities.Cron.csproj", "{FE6ECF63-D3FC-44EA-8405-C2A73F7C00C8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Runtime.Hosting", "src\core\Elsa.Runtime.Hosting\Elsa.Runtime.Hosting.csproj", "{4728D287-E4F4-4219-8066-924B53E6E17C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -161,6 +167,18 @@ Global
|
|||
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E4B71DC4-3E73-49C3-9B4E-CA13909F222D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E4B71DC4-3E73-49C3-9B4E-CA13909F222D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E4B71DC4-3E73-49C3-9B4E-CA13909F222D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E4B71DC4-3E73-49C3-9B4E-CA13909F222D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FE6ECF63-D3FC-44EA-8405-C2A73F7C00C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FE6ECF63-D3FC-44EA-8405-C2A73F7C00C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FE6ECF63-D3FC-44EA-8405-C2A73F7C00C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FE6ECF63-D3FC-44EA-8405-C2A73F7C00C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4728D287-E4F4-4219-8066-924B53E6E17C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4728D287-E4F4-4219-8066-924B53E6E17C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4728D287-E4F4-4219-8066-924B53E6E17C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4728D287-E4F4-4219-8066-924B53E6E17C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -192,6 +210,9 @@ Global
|
|||
{089E23E7-0B8D-4BB6-949D-EB669C116D9E} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
{D20FCB88-9DCA-49EA-9CC2-5B94DD935D30} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92} = {B33F1927-FF0A-4826-80C6-F480E9C43892}
|
||||
{E4B71DC4-3E73-49C3-9B4E-CA13909F222D} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
|
||||
{FE6ECF63-D3FC-44EA-8405-C2A73F7C00C8} = {B33F1927-FF0A-4826-80C6-F480E9C43892}
|
||||
{4728D287-E4F4-4219-8066-924B53E6E17C} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using Elsa.Expressions;
|
||||
using Elsa.Models;
|
||||
|
||||
namespace Elsa.Activities.Cron.Activities
|
||||
{
|
||||
public class CronTrigger : Activity
|
||||
{
|
||||
public WorkflowExpression<string> CronExpression { get; set; }
|
||||
public DateTime? StartTimestamp { get; set; }
|
||||
}
|
||||
}
|
||||
27
src/activities/Elsa.Activities.Cron/ActivityDescriptors.cs
Normal file
27
src/activities/Elsa.Activities.Cron/ActivityDescriptors.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System.Collections.Generic;
|
||||
using Elsa.Activities.Cron.Activities;
|
||||
using Elsa.Models;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace Elsa.Activities.Cron
|
||||
{
|
||||
public class ActivityDescriptors : ActivityDescriptorProviderBase
|
||||
{
|
||||
public ActivityDescriptors(IStringLocalizer<ActivityDescriptors> localizer)
|
||||
{
|
||||
T = localizer;
|
||||
}
|
||||
|
||||
private IStringLocalizer<ActivityDescriptors> T { get; }
|
||||
private LocalizedString Category => T["Triggers"];
|
||||
|
||||
protected override IEnumerable<ActivityDescriptor> Describe()
|
||||
{
|
||||
yield return ActivityDescriptor.ForTrigger<CronTrigger>(
|
||||
Category,
|
||||
T["Cron Trigger"],
|
||||
T["Triggers at specified intervals using CRON expressions."],
|
||||
T["Done"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Cron.Activities;
|
||||
using Elsa.Handlers;
|
||||
using Elsa.Models;
|
||||
using Elsa.Results;
|
||||
using NCrontab;
|
||||
using NodaTime;
|
||||
using NodaTime.Extensions;
|
||||
|
||||
namespace Elsa.Activities.Cron.Drivers
|
||||
{
|
||||
public class CronTriggerDriver : ActivityDriver<CronTrigger>
|
||||
{
|
||||
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
|
||||
private readonly IClock clock;
|
||||
|
||||
public CronTriggerDriver(IWorkflowExpressionEvaluator expressionEvaluator, IClock clock)
|
||||
{
|
||||
this.expressionEvaluator = expressionEvaluator;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
protected override async Task<bool> OnCanExecuteAsync(CronTrigger activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken)
|
||||
{
|
||||
return activity.StartTimestamp == null || await IsExpiredAsync(activity, workflowContext, cancellationToken);
|
||||
}
|
||||
|
||||
protected override ActivityExecutionResult OnExecute(CronTrigger activity, WorkflowExecutionContext workflowContext)
|
||||
{
|
||||
if (activity.StartTimestamp == null)
|
||||
activity.StartTimestamp = clock.GetCurrentInstant().ToDateTimeUtc();
|
||||
|
||||
return Halt();
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnResumeAsync(CronTrigger activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var isExpired = await IsExpiredAsync(activity, workflowContext, cancellationToken);
|
||||
|
||||
return isExpired ? (ActivityExecutionResult) Endpoint("Done") : Halt();
|
||||
}
|
||||
|
||||
private async Task<bool> IsExpiredAsync(CronTrigger activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var cronExpression = await expressionEvaluator.EvaluateAsync(activity.CronExpression, workflowContext, cancellationToken);
|
||||
var schedule = CrontabSchedule.Parse(cronExpression);
|
||||
var now = clock.GetCurrentInstant().ToDateTimeUtc();
|
||||
var startTimestamp = activity.StartTimestamp ?? now;
|
||||
var nextOccurrence = schedule.GetNextOccurrence(startTimestamp);
|
||||
|
||||
return now >= nextOccurrence;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<Authors>Sipke Schoorstra</Authors>
|
||||
<Description>Elsa is a set of workflowing libraries and tools to enable super-fast workflowing capabilities in any .NET Core application.</Description>
|
||||
<Copyright>2019</Copyright>
|
||||
<PackageProjectUrl>https://github.com/sfmskywalker/Elsa</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/sfmskywalker/Elsa</RepositoryUrl>
|
||||
<RepositoryType>GitHub</RepositoryType>
|
||||
<PackageTags>elsa, workflows, orchard</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Runtime.Abstractions\Elsa.Runtime.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="NCrontab" Version="3.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using Elsa.Activities.Cron.Drivers;
|
||||
using Elsa.Activities.Cron.HostedServices;
|
||||
using Elsa.Activities.Cron.Options;
|
||||
using Elsa.Extensions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Activities.Cron.Extensions
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddCronDescriptors(this IServiceCollection services)
|
||||
{
|
||||
return services.AddActivityDescriptors<ActivityDescriptors>();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddCronDrivers(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
return services
|
||||
.AddCronDescriptors()
|
||||
.AddOptions()
|
||||
.Configure<CronOptions>(configuration)
|
||||
.AddHostedService<CronHostedService>()
|
||||
.AddActivityDriver<CronTriggerDriver>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Activities.Cron.Activities;
|
||||
using Elsa.Activities.Cron.Options;
|
||||
using Elsa.Models;
|
||||
using Elsa.Runtime;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.Activities.Cron.HostedServices
|
||||
{
|
||||
public class CronHostedService : BackgroundService
|
||||
{
|
||||
private readonly IWorkflowHost workflowHost;
|
||||
private readonly IOptions<CronOptions> options;
|
||||
private readonly ILogger<CronHostedService> logger;
|
||||
|
||||
public CronHostedService(IWorkflowHost workflowHost, IOptions<CronOptions> options, ILogger<CronHostedService> logger)
|
||||
{
|
||||
this.workflowHost = workflowHost;
|
||||
this.options = options;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await workflowHost.TriggerWorkflowAsync(nameof(CronTrigger), Variables.Empty, stoppingToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, $"Exception occurred while invoking workflows.");
|
||||
}
|
||||
|
||||
await Task.Delay(options.Value.SweepInterval.ToDuration().ToTimeSpan(), stoppingToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/activities/Elsa.Activities.Cron/Options/CronOptions.cs
Normal file
14
src/activities/Elsa.Activities.Cron/Options/CronOptions.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using NodaTime;
|
||||
|
||||
namespace Elsa.Activities.Cron.Options
|
||||
{
|
||||
public class CronOptions
|
||||
{
|
||||
public CronOptions()
|
||||
{
|
||||
SweepInterval = Period.FromMinutes(1);
|
||||
}
|
||||
|
||||
public Period SweepInterval { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ namespace Elsa.Activities.Email.Drivers
|
|||
};
|
||||
|
||||
mailMessage.To.Add(to);
|
||||
smtpClient.SendAsync(mailMessage, null);
|
||||
await smtpClient.SendMailAsync(mailMessage);
|
||||
|
||||
return Endpoint("Done");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace Elsa.Serialization.Tokenizers
|
|||
private readonly ITokenizerInvoker tokenizerInvoker;
|
||||
private readonly IActivityLibrary activityLibrary;
|
||||
private readonly IClock clock;
|
||||
private readonly JsonSerializerSettings _serializerSettings;
|
||||
private readonly JsonSerializerSettings serializerSettings;
|
||||
private readonly JsonSerializer jsonSerializer;
|
||||
|
||||
public WorkflowTokenizer(ITokenizerInvoker tokenizerInvoker, IActivityLibrary activityLibrary, IClock clock)
|
||||
|
|
@ -30,14 +30,14 @@ namespace Elsa.Serialization.Tokenizers
|
|||
this.activityLibrary = activityLibrary;
|
||||
this.clock = clock;
|
||||
|
||||
_serializerSettings = new JsonSerializerSettings
|
||||
serializerSettings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
}
|
||||
.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||
|
||||
_serializerSettings.Converters.Add(new StringEnumConverter());
|
||||
jsonSerializer = JsonSerializer.Create(_serializerSettings);
|
||||
serializerSettings.Converters.Add(new StringEnumConverter());
|
||||
jsonSerializer = JsonSerializer.Create(serializerSettings);
|
||||
}
|
||||
|
||||
public async Task<JToken> TokenizeWorkflowAsync(Workflow value, CancellationToken cancellationToken)
|
||||
|
|
@ -120,7 +120,7 @@ namespace Elsa.Serialization.Tokenizers
|
|||
var name = token["name"].Value<string>();
|
||||
var descriptor = await GetActivityDescriptorAsync(name, cancellationToken);
|
||||
var activityType = descriptor?.ActivityType ?? typeof(UnknownActivity);
|
||||
var activity = (IActivity) token.ToObject(activityType);
|
||||
var activity = (IActivity) jsonSerializer.Deserialize(token.CreateReader(), activityType);
|
||||
|
||||
activity.Descriptor = descriptor;
|
||||
return activity;
|
||||
|
|
@ -267,7 +267,7 @@ namespace Elsa.Serialization.Tokenizers
|
|||
{
|
||||
var models = (JArray) token["executionLog"] ?? new JArray();
|
||||
|
||||
return JsonConvert.DeserializeObject<IList<LogEntry>>(models.ToString(), _serializerSettings);
|
||||
return JsonConvert.DeserializeObject<IList<LogEntry>>(models.ToString(), serializerSettings);
|
||||
}
|
||||
|
||||
private IEnumerable<Connection> DeserializeConnections(JToken token, IDictionary<string, IActivity> activityDictionary)
|
||||
|
|
|
|||
11
src/core/Elsa.Runtime.Hosting/Elsa.Runtime.Hosting.csproj
Normal file
11
src/core/Elsa.Runtime.Hosting/Elsa.Runtime.Hosting.csproj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NodaTime" Version="2.4.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using System.ComponentModel;
|
||||
using Elsa.Runtime.Hosting.TypeConverters;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Runtime.Hosting.Extensions
|
||||
{
|
||||
public static class ProgramExtensions
|
||||
{
|
||||
public static void ConfigureTypeConverters()
|
||||
{
|
||||
TypeDescriptor.AddAttributes(
|
||||
typeof(Period),
|
||||
new TypeConverterAttribute(typeof(PeriodTypeConverter)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using NodaTime.Text;
|
||||
|
||||
namespace Elsa.Runtime.Hosting.TypeConverters
|
||||
{
|
||||
public class PeriodTypeConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string s)
|
||||
{
|
||||
return PeriodPattern.Roundtrip.Parse(s).Value;
|
||||
}
|
||||
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ namespace Elsa.Runtime.Extensions
|
|||
return services
|
||||
.AddWorkflowsCore()
|
||||
.AddWorkflowsInvoker()
|
||||
.AddScoped<IWorkflowHost, WorkflowHost>();
|
||||
.AddSingleton<IWorkflowHost, WorkflowHost>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,6 +31,7 @@ namespace Elsa.Runtime
|
|||
public async Task<WorkflowExecutionContext> StartWorkflowAsync(Workflow workflow, IActivity startActivity, Variables arguments, CancellationToken cancellationToken)
|
||||
{
|
||||
var workflowInstance = await workflowSerializer.DeriveAsync(workflow, cancellationToken);
|
||||
startActivity = workflowInstance.Activities.Single(x => x.Id == startActivity.Id);
|
||||
return await invoker.InvokeAsync(workflowInstance, startActivity, arguments, cancellationToken);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Console\Elsa.Web.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Cron\Elsa.Web.Activities.Cron.csproj" />
|
||||
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Email\Elsa.Web.Activities.Email.csproj" />
|
||||
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Http\Elsa.Web.Activities.Http.csproj" />
|
||||
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Primitives\Elsa.Web.Activities.Primitives.csproj" />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Threading.Tasks;
|
||||
using Elsa.Runtime.Hosting.Extensions;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
|
|
@ -13,7 +14,10 @@ namespace SampleHost.Web
|
|||
await host.RunAsync();
|
||||
}
|
||||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder<Startup>(args);
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
|
||||
{
|
||||
ProgramExtensions.ConfigureTypeConverters();
|
||||
return WebHost.CreateDefaultBuilder<Startup>(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,11 +20,13 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Cron\Elsa.Activities.Cron.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Primitives\Elsa.Activities.Primitives.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Persistence.FileSystem\Elsa.Persistence.FileSystem.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Runtime.Hosting\Elsa.Runtime.Hosting.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa.Runtime\Elsa.Runtime.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Elsa.Activities.Console.Extensions;
|
||||
using Elsa.Activities.Cron.Extensions;
|
||||
using Elsa.Activities.Email.Extensions;
|
||||
using Elsa.Activities.Http.Extensions;
|
||||
using Elsa.Activities.Primitives.Extensions;
|
||||
|
|
@ -31,7 +32,8 @@ namespace SampleHost.Web
|
|||
.AddPrimitiveWorkflowDrivers()
|
||||
.AddConsoleWorkflowDrivers()
|
||||
.AddHttpWorkflowDrivers()
|
||||
.AddEmailDrivers(Configuration.GetSection("Smtp"));
|
||||
.AddEmailDrivers(Configuration.GetSection("Smtp"))
|
||||
.AddCronDrivers(Configuration.GetSection("Cron"));
|
||||
|
||||
services
|
||||
.AddMvc()
|
||||
|
|
|
|||
|
|
@ -15,5 +15,8 @@
|
|||
"Credentials": {
|
||||
"Type": "None"
|
||||
}
|
||||
},
|
||||
"Cron": {
|
||||
"SweepInterval": "PT10S"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
using Elsa.Activities.Cron.Activities;
|
||||
using Elsa.Web.Activities.Cron.ViewModels;
|
||||
using Elsa.Web.Components.ViewModels;
|
||||
using Elsa.Web.Drivers;
|
||||
|
||||
namespace Elsa.Web.Activities.Cron.Display
|
||||
{
|
||||
public class CronTriggerDisplay : ActivityDisplayDriver<CronTrigger, CronTriggerViewModel>
|
||||
{
|
||||
protected override void EditActivity(CronTrigger activity, CronTriggerViewModel model)
|
||||
{
|
||||
model.CronExpression = new ExpressionViewModel(activity.CronExpression);
|
||||
}
|
||||
|
||||
protected override void UpdateActivity(CronTriggerViewModel model, CronTrigger activity)
|
||||
{
|
||||
activity.CronExpression = model.CronExpression.ToWorkflowExpression<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<Authors>Sipke Schoorstra</Authors>
|
||||
<Description>Elsa is a set of workflowing libraries and tools to enable super-fast workflowing capabilities in any .NET Core application.</Description>
|
||||
<Copyright>2019</Copyright>
|
||||
<PackageProjectUrl>https://github.com/sfmskywalker/Elsa</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/sfmskywalker/Elsa</RepositoryUrl>
|
||||
<RepositoryType>GitHub</RepositoryType>
|
||||
<PackageTags>elsa, workflows, orchard</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\activities\Elsa.Activities.Cron\Elsa.Activities.Cron.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Web.Abstractions\Elsa.Web.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\Elsa.Web.Components\Elsa.Web.Components.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-70705" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
7
src/web/modules/Elsa.Web.Activities.Cron/Manifest.cs
Normal file
7
src/web/modules/Elsa.Web.Activities.Cron/Manifest.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
using OrchardCore.Modules.Manifest;
|
||||
|
||||
[assembly: Module(
|
||||
Name = "Cron Activities",
|
||||
Category = "Elsa Workflows",
|
||||
Description = "Provides a Cron Trigger activity."
|
||||
)]
|
||||
18
src/web/modules/Elsa.Web.Activities.Cron/Startup.cs
Normal file
18
src/web/modules/Elsa.Web.Activities.Cron/Startup.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using Elsa.Activities.Cron.Extensions;
|
||||
using Elsa.Web.Activities.Cron.Display;
|
||||
using Elsa.Web.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OrchardCore.Modules;
|
||||
|
||||
namespace Elsa.Web.Activities.Cron
|
||||
{
|
||||
public class Startup : StartupBase
|
||||
{
|
||||
public override void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddCronDescriptors()
|
||||
.AddActivityDisplay<CronTriggerDisplay>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
using Elsa.Web.Components.ViewModels;
|
||||
|
||||
namespace Elsa.Web.Activities.Cron.ViewModels
|
||||
{
|
||||
public class CronTriggerViewModel
|
||||
{
|
||||
public ExpressionViewModel CronExpression { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
@model ActivityShapeModel<CronTrigger>
|
||||
@{
|
||||
var activityDescriptor = Model.Activity.Descriptor;
|
||||
}
|
||||
<h4 class="card-title"><i class="fas fa-globe"></i>@activityDescriptor.DisplayText</h4>
|
||||
<p>@activityDescriptor.Description</p>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
@model ActivityShapeModel<CronTrigger>
|
||||
|
||||
<header>
|
||||
<h4><i class="fas fa-globe"></i>@Model.DisplayText</h4>
|
||||
<i>"@($"{Model.Activity.CronExpression}")"</i>
|
||||
</header>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@model CronTriggerViewModel
|
||||
<div class="form-group">
|
||||
<label asp-for="CronExpression">@T["Cron Expression"]</label>
|
||||
<vc:expression-editor model="@Model.CronExpression" prefix="@Html.NameFor(m => m.CronExpression)"></vc:expression-editor>
|
||||
<span asp-validation-for="CronExpression" class="text-danger"></span>
|
||||
<small class="form-text text-muted">@T["Enter a crontab expression. See https://crontab.guru/."]</small>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@using Elsa.Web.ViewModels
|
||||
@using Elsa.Web.Activities.Cron.ViewModels
|
||||
@using Elsa.Activities.Cron.Activities
|
||||
@using OrchardCore.Mvc.Core.Utilities
|
||||
@inherits OrchardCore.DisplayManagement.Razor.RazorPage<TModel>
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper *, Elsa.Web.Components
|
||||
Loading…
Reference in a new issue