Update package descriptions and renamed some activities

This commit is contained in:
Sipke Schoorstra 2019-10-27 17:31:50 +01:00
parent 38a4901896
commit e162391c30
44 changed files with 790 additions and 658 deletions

View file

@ -38,8 +38,12 @@ Version 2.0
- [ ] Generic Command & Event Activities
- [ ] Workflow Host REST API
- [ ] Workflow Host gRPC API
- [ ] Workflow Server
- [ ] Distributed Hosting Support (support for multi-node environments)
- [ ] Localization Support
- [ ] More activities
- [ ] Workflow Designer UI improvements
- [ ] Activity Editor UI improvements
Version 3.0

View file

@ -4,13 +4,19 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following Console activities:
* ReadLine
* WriteLine
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
<PackageTags>elsa, workflows</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -2,6 +2,25 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following control flow activities:
* ForEach
* Fork
* IfElse
* Join
* Switch
* While
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,13 +4,18 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following Dropbox activities:
* SaveToDropbox
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard, dropbox</PackageTags>
<PackageTags>elsa, workflows, dropbox</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,13 +4,18 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following Email activities:
* SendEmail
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
<PackageTags>elsa, workflows, email, smtp</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -1,135 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Http.Extensions;
using Elsa.Activities.Http.Models;
using Elsa.Activities.Http.Services;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Extensions;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
namespace Elsa.Activities.Http.Activities
{
[ActivityDefinition(
Category = "HTTP",
DisplayName = "Receive HTTP Request",
Description = "Receive an incoming HTTP request.",
RuntimeDescription = "x => !!x.state.path ? `Handle <strong>${ x.state.method } ${ x.state.path }</strong>.` : x.definition.description",
Outcomes = new[] { OutcomeNames.Done }
)]
public class HttpRequestEvent : Activity
{
public static Uri GetPath(JObject state)
{
return state.GetState<Uri>(nameof(Path));
}
public static string GetMethod(JObject state)
{
return state.GetState<string>(nameof(Method));
}
private readonly IHttpContextAccessor httpContextAccessor;
private readonly IEnumerable<IContentFormatter> contentFormatters;
public HttpRequestEvent(
IHttpContextAccessor httpContextAccessor,
IEnumerable<IContentFormatter> contentFormatters)
{
this.httpContextAccessor = httpContextAccessor;
this.contentFormatters = contentFormatters;
}
/// <summary>
/// The path that triggers this activity.
/// </summary>
[ActivityProperty(Hint = "The relative path that triggers this activity.")]
public Uri Path
{
get => GetState<Uri>();
set => SetState(value);
}
/// <summary>
/// The HTTP method that triggers this activity.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP method that triggers this activity."
)]
[SelectOptions("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD")]
public string Method
{
get => GetState<string>();
set => SetState(value);
}
/// <summary>
/// A value indicating whether the HTTP request content body should be read and stored as part of the HTTP request model.
/// The stored format depends on the content-type header.
/// </summary>
[ActivityProperty(
Hint =
"A value indicating whether the HTTP request content body should be read and stored as part of the HTTP request model. The stored format depends on the content-type header."
)]
public bool ReadContent
{
get => GetState<bool>();
set => SetState(value);
}
protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext workflowContext)
{
return Halt(true);
}
protected override async Task<ActivityExecutionResult> OnResumeAsync(
WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var request = httpContextAccessor.HttpContext.Request;
var model = new HttpRequestModel
{
Path = new Uri(request.Path.ToString(), UriKind.Relative),
QueryString = request.Query.ToDictionary(x => x.Key, x => new StringValuesModel(x.Value)),
Headers = request.Headers.ToDictionary(x => x.Key, x => new StringValuesModel(x.Value)),
Method = request.Method
};
if (ReadContent)
{
if (request.HasFormContentType)
{
model.Form = (await request.ReadFormAsync(cancellationToken)).ToDictionary(
x => x.Key,
x => new StringValuesModel(x.Value)
);
}
var parser = SelectContentParser(request.ContentType);
var content = await request.ReadContentAsBytesAsync(cancellationToken);
model.Body = await parser.ParseAsync(content, request.ContentType);
}
Output["Content"] = model;
workflowContext.CurrentScope.LastResult = model;
return Done();
}
private IContentFormatter SelectContentParser(string contentType)
{
var formatters = contentFormatters.OrderByDescending(x => x.Priority).ToList();
return formatters.FirstOrDefault(
x => x.SupportedContentTypes.Contains(contentType, StringComparer.OrdinalIgnoreCase)
) ?? formatters.Last();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Http.Extensions;
using Elsa.Activities.Http.Models;
using Elsa.Activities.Http.Services;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Extensions;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
namespace Elsa.Activities.Http.Activities
{
[ActivityDefinition(
Category = "HTTP",
DisplayName = "Receive HTTP Request",
Description = "Receive an incoming HTTP request.",
RuntimeDescription = "x => !!x.state.path ? `Handle <strong>${ x.state.method } ${ x.state.path }</strong>.` : x.definition.description",
Outcomes = new[] { OutcomeNames.Done }
)]
public class ReceiveHttpRequest : Activity
{
public static Uri GetPath(JObject state)
{
return state.GetState<Uri>(nameof(Path));
}
public static string GetMethod(JObject state)
{
return state.GetState<string>(nameof(Method));
}
private readonly IHttpContextAccessor httpContextAccessor;
private readonly IEnumerable<IContentFormatter> contentFormatters;
public ReceiveHttpRequest(
IHttpContextAccessor httpContextAccessor,
IEnumerable<IContentFormatter> contentFormatters)
{
this.httpContextAccessor = httpContextAccessor;
this.contentFormatters = contentFormatters;
}
/// <summary>
/// The path that triggers this activity.
/// </summary>
[ActivityProperty(Hint = "The relative path that triggers this activity.")]
public Uri Path
{
get => GetState<Uri>();
set => SetState(value);
}
/// <summary>
/// The HTTP method that triggers this activity.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP method that triggers this activity."
)]
[SelectOptions("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD")]
public string Method
{
get => GetState<string>();
set => SetState(value);
}
/// <summary>
/// A value indicating whether the HTTP request content body should be read and stored as part of the HTTP request model.
/// The stored format depends on the content-type header.
/// </summary>
[ActivityProperty(
Hint =
"A value indicating whether the HTTP request content body should be read and stored as part of the HTTP request model. The stored format depends on the content-type header."
)]
public bool ReadContent
{
get => GetState<bool>();
set => SetState(value);
}
protected override ActivityExecutionResult OnExecute(WorkflowExecutionContext workflowContext)
{
return Halt(true);
}
protected override async Task<ActivityExecutionResult> OnResumeAsync(
WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var request = httpContextAccessor.HttpContext.Request;
var model = new HttpRequestModel
{
Path = new Uri(request.Path.ToString(), UriKind.Relative),
QueryString = request.Query.ToDictionary(x => x.Key, x => new StringValuesModel(x.Value)),
Headers = request.Headers.ToDictionary(x => x.Key, x => new StringValuesModel(x.Value)),
Method = request.Method
};
if (ReadContent)
{
if (request.HasFormContentType)
{
model.Form = (await request.ReadFormAsync(cancellationToken)).ToDictionary(
x => x.Key,
x => new StringValuesModel(x.Value)
);
}
var parser = SelectContentParser(request.ContentType);
var content = await request.ReadContentAsBytesAsync(cancellationToken);
model.Body = await parser.ParseAsync(content, request.ContentType);
}
Output["Content"] = model;
workflowContext.CurrentScope.LastResult = model;
return Done();
}
private IContentFormatter SelectContentParser(string contentType)
{
var formatters = contentFormatters.OrderByDescending(x => x.Priority).ToList();
return formatters.FirstOrDefault(
x => x.SupportedContentTypes.Contains(contentType, StringComparer.OrdinalIgnoreCase)
) ?? formatters.Last();
}
}
}

View file

@ -1,267 +1,270 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Http.Models;
using Elsa.Activities.Http.Services;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Expressions;
using Elsa.Extensions;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.AspNetCore.Http;
namespace Elsa.Activities.Http.Activities
{
[ActivityDefinition(
Category = "HTTP",
DisplayName = "Send HTTP Request",
Description = "Send an HTTP request.",
RuntimeDescription = "x => !!x.state.url ? `Send HTTP <strong>${ x.state.method } ${ x.state.url.expression }</strong>.` : x.definition.description",
Outcomes = "x => !!x.state.supportedStatusCodes ? x.state.supportedStatusCodes : []"
)]
public class HttpRequestAction : Activity
{
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
private readonly HttpClient httpClient;
private readonly IEnumerable<IContentFormatter> contentFormatters;
public HttpRequestAction(
IWorkflowExpressionEvaluator expressionEvaluator,
IHttpClientFactory httpClientFactory,
IEnumerable<IContentFormatter> contentFormatters)
{
this.expressionEvaluator = expressionEvaluator;
httpClient = httpClientFactory.CreateClient(nameof(HttpRequestAction));
this.contentFormatters = contentFormatters;
}
/// <summary>
/// The URL to invoke.
/// </summary>
[ActivityProperty(Hint = "The URL to send the HTTP request to.")]
public WorkflowExpression<Uri> Url
{
get
{
var url = GetState<WorkflowExpression<string>>();
if (url != null && !string.IsNullOrWhiteSpace(url.Expression) && Uri.TryCreate(
url.Expression,
UriKind.RelativeOrAbsolute,
out var uri
))
return new WorkflowExpression<Uri>(url.Syntax, uri.ToString());
return new WorkflowExpression<Uri>(LiteralEvaluator.SyntaxName, "");
}
set => SetState(new WorkflowExpression<string>(value.Syntax, value.Expression));
}
/// <summary>
/// The HTTP method to use.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP method to use when making the request."
)]
[SelectOptions("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD")]
public string Method
{
get => GetState(() => "GET");
set => SetState(value);
}
/// <summary>
/// The body to send along with the request.
/// </summary>
[ActivityProperty(Hint = "The HTTP content to send along with the request.")]
[ExpressionOptions(Multiline = true)]
public WorkflowExpression<string> Content
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
/// <summary>
/// The Content Type header to send along with the request body.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The content type to send with the request (if applicable)."
)]
[SelectOptions("text/plain", "text/html", "application/json", "application/xml")]
public WorkflowExpression<string> ContentType
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
[ActivityProperty(
Hint = "The Authorization header value to send."
)]
public WorkflowExpression<string> Authorization
{
get => GetState<WorkflowExpression<string>>();
set => SetState(value);
}
/// <summary>
/// The headers to send along with the request.
/// </summary>
[ActivityProperty(Hint = "The headers to send along with the request. One 'header: value' pair per line.")]
public WorkflowExpression<string> RequestHeaders
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
[ActivityProperty(Hint = "Check to read the content of the response.")]
public bool ReadContent
{
get => GetState(() => true);
set => SetState(value);
}
/// <summary>
/// A list of HTTP status codes this activity can handle.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.List,
Hint = "A list of possible HTTP status codes to handle, comma-separated. Example: 200, 400, 404"
)]
public HashSet<int> SupportedStatusCodes
{
get => GetState(() => new HashSet<int> { 200 });
set => SetState(value);
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var request = await CreateRequestAsync(workflowContext, cancellationToken);
var response = await httpClient.SendAsync(request, cancellationToken);
var hasContent = response.Content != null;
var contentType = response.Content?.Headers.ContentType.MediaType;
var responseModel = new HttpResponseModel
{
StatusCode = response.StatusCode,
Headers = new Dictionary<string, string[]>(
response.Headers.ToDictionary(x => x.Key, x => x.Value.ToArray())
)
};
if (hasContent && ReadContent)
{
var formatter = SelectContentFormatter(contentType);
responseModel.Content = await response.Content.ReadAsByteArrayAsync();
responseModel.ParsedContent = await formatter.ParseAsync(responseModel.Content, contentType);
}
workflowContext.SetLastResult(responseModel);
Output["Response"] = responseModel;
var statusEndpoint = ((int) response.StatusCode).ToString();
return Outcomes(new[] { OutcomeNames.Done, statusEndpoint });
}
private IContentFormatter SelectContentFormatter(string contentType)
{
var formatters = contentFormatters.OrderByDescending(x => x.Priority).ToList();
return formatters.FirstOrDefault(
x => x.SupportedContentTypes.Contains(contentType, StringComparer.OrdinalIgnoreCase)
) ?? formatters.Last();
}
private async Task<HttpRequestMessage> CreateRequestAsync(WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var methodSupportsBody = GetMethodSupportsBody(Method);
var uri = await expressionEvaluator.EvaluateAsync(Url, workflowContext, cancellationToken);
var request = new HttpRequestMessage(new HttpMethod(Method), uri);
var authorizationHeaderValue = await expressionEvaluator.EvaluateAsync(
Authorization,
workflowContext,
cancellationToken
);
var requestHeaders = await ParseRequestHeadersAsync(workflowContext, cancellationToken);
if (methodSupportsBody)
{
var body = await expressionEvaluator.EvaluateAsync(Content, workflowContext, cancellationToken);
var contentType = await expressionEvaluator.EvaluateAsync(
ContentType,
workflowContext,
cancellationToken
);
if (!string.IsNullOrWhiteSpace(body))
{
request.Content = new StringContent(body, Encoding.UTF8, contentType);
}
}
if (!string.IsNullOrWhiteSpace(authorizationHeaderValue))
{
request.Headers.Authorization = AuthenticationHeaderValue.Parse(authorizationHeaderValue);
}
foreach (var header in requestHeaders)
{
request.Headers.Add(header.Key, header.Value.AsEnumerable());
}
return request;
}
private async Task<IHeaderDictionary> ParseRequestHeadersAsync(WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var headersText = await expressionEvaluator.EvaluateAsync(
RequestHeaders,
workflowContext,
cancellationToken
);
var headers = new HeaderDictionary();
if (headersText != null)
{
var headersQuery =
from line in Regex.Split(headersText, "\\n", RegexOptions.Multiline)
let pair = line.Split(':', '=')
select new KeyValuePair<string, string>(pair[0], pair[1]);
foreach (var header in headersQuery)
{
var headerValueExpression = new WorkflowExpression<string>(RequestHeaders.Syntax, header.Value);
var headerValue = await expressionEvaluator.EvaluateAsync(
headerValueExpression,
workflowContext,
cancellationToken
);
headers.Add(header.Key, headerValue);
}
}
return headers;
}
private bool GetMethodSupportsBody(string method)
{
var methods = new[] { "POST", "PUT", "PATCH" };
return methods.Contains(method, StringComparer.InvariantCultureIgnoreCase);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Http.Models;
using Elsa.Activities.Http.Services;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Expressions;
using Elsa.Extensions;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.AspNetCore.Http;
namespace Elsa.Activities.Http.Activities
{
[ActivityDefinition(
Category = "HTTP",
DisplayName = "Send HTTP Request",
Description = "Send an HTTP request.",
RuntimeDescription = "x => !!x.state.url ? `Send HTTP <strong>${ x.state.method } ${ x.state.url.expression }</strong>.` : x.definition.description",
Outcomes = "x => !!x.state.supportedStatusCodes ? x.state.supportedStatusCodes : []"
)]
public class SendHttpRequest : Activity
{
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
private readonly HttpClient httpClient;
private readonly IEnumerable<IContentFormatter> contentFormatters;
public SendHttpRequest(
IWorkflowExpressionEvaluator expressionEvaluator,
IHttpClientFactory httpClientFactory,
IEnumerable<IContentFormatter> contentFormatters)
{
this.expressionEvaluator = expressionEvaluator;
httpClient = httpClientFactory.CreateClient(nameof(SendHttpRequest));
this.contentFormatters = contentFormatters;
}
/// <summary>
/// The URL to invoke.
/// </summary>
[ActivityProperty(Hint = "The URL to send the HTTP request to.")]
public WorkflowExpression<Uri> Url
{
get
{
var url = GetState<WorkflowExpression<string>>();
if (url != null && !string.IsNullOrWhiteSpace(url.Expression) && Uri.TryCreate(
url.Expression,
UriKind.RelativeOrAbsolute,
out var uri
))
return new WorkflowExpression<Uri>(url.Syntax, uri.ToString());
return new WorkflowExpression<Uri>(LiteralEvaluator.SyntaxName, "");
}
set => SetState(new WorkflowExpression<string>(value.Syntax, value.Expression));
}
/// <summary>
/// The HTTP method to use.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP method to use when making the request."
)]
[SelectOptions("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD")]
public string Method
{
get => GetState(() => "GET");
set => SetState(value);
}
/// <summary>
/// The body to send along with the request.
/// </summary>
[ActivityProperty(Hint = "The HTTP content to send along with the request.")]
[ExpressionOptions(Multiline = true)]
public WorkflowExpression<string> Content
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
/// <summary>
/// The Content Type header to send along with the request body.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The content type to send with the request (if applicable)."
)]
[SelectOptions("text/plain", "text/html", "application/json", "application/xml")]
public WorkflowExpression<string> ContentType
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
[ActivityProperty(
Hint = "The Authorization header value to send."
)]
public WorkflowExpression<string> Authorization
{
get => GetState<WorkflowExpression<string>>();
set => SetState(value);
}
/// <summary>
/// The headers to send along with the request.
/// </summary>
[ActivityProperty(Hint = "The headers to send along with the request. One 'header: value' pair per line.")]
public WorkflowExpression<string> RequestHeaders
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
[ActivityProperty(Hint = "Check to read the content of the response.")]
public bool ReadContent
{
get => GetState(() => true);
set => SetState(value);
}
/// <summary>
/// A list of HTTP status codes this activity can handle.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.List,
Hint = "A list of possible HTTP status codes to handle, comma-separated. Example: 200, 400, 404"
)]
public HashSet<int> SupportedStatusCodes
{
get => GetState(() => new HashSet<int> { 200 });
set => SetState(value);
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var request = await CreateRequestAsync(workflowContext, cancellationToken);
var response = await httpClient.SendAsync(request, cancellationToken);
var hasContent = response.Content != null;
var contentType = response.Content?.Headers.ContentType.MediaType;
var responseModel = new HttpResponseModel
{
StatusCode = response.StatusCode,
Headers = new Dictionary<string, string[]>(
response.Headers.ToDictionary(x => x.Key, x => x.Value.ToArray())
)
};
if (hasContent && ReadContent)
{
var formatter = SelectContentFormatter(contentType);
responseModel.Content = await response.Content.ReadAsByteArrayAsync();
responseModel.ParsedContent = await formatter.ParseAsync(responseModel.Content, contentType);
}
workflowContext.SetLastResult(responseModel);
Output["Response"] = responseModel;
var statusEndpoint = ((int)response.StatusCode).ToString();
return Outcomes(new[] { OutcomeNames.Done, statusEndpoint });
}
private IContentFormatter SelectContentFormatter(string contentType)
{
var formatters = contentFormatters.OrderByDescending(x => x.Priority).ToList();
return formatters.FirstOrDefault(
x => x.SupportedContentTypes.Contains(contentType, StringComparer.OrdinalIgnoreCase)
) ?? formatters.Last();
}
private async Task<HttpRequestMessage> CreateRequestAsync(
WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var methodSupportsBody = GetMethodSupportsBody(Method);
var uri = await expressionEvaluator.EvaluateAsync(Url, workflowContext, cancellationToken);
var request = new HttpRequestMessage(new HttpMethod(Method), uri);
var authorizationHeaderValue = await expressionEvaluator.EvaluateAsync(
Authorization,
workflowContext,
cancellationToken
);
var requestHeaders = await ParseRequestHeadersAsync(workflowContext, cancellationToken);
if (methodSupportsBody)
{
var body = await expressionEvaluator.EvaluateAsync(Content, workflowContext, cancellationToken);
var contentType = await expressionEvaluator.EvaluateAsync(
ContentType,
workflowContext,
cancellationToken
);
if (!string.IsNullOrWhiteSpace(body))
{
request.Content = new StringContent(body, Encoding.UTF8, contentType);
}
}
if (!string.IsNullOrWhiteSpace(authorizationHeaderValue))
{
request.Headers.Authorization = AuthenticationHeaderValue.Parse(authorizationHeaderValue);
}
foreach (var header in requestHeaders)
{
request.Headers.Add(header.Key, header.Value.AsEnumerable());
}
return request;
}
private async Task<IHeaderDictionary> ParseRequestHeadersAsync(
WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var headersText = await expressionEvaluator.EvaluateAsync(
RequestHeaders,
workflowContext,
cancellationToken
);
var headers = new HeaderDictionary();
if (headersText != null)
{
var headersQuery =
from line in Regex.Split(headersText, "\\n", RegexOptions.Multiline)
let pair = line.Split(':', '=')
select new KeyValuePair<string, string>(pair[0], pair[1]);
foreach (var header in headersQuery)
{
var headerValueExpression = new WorkflowExpression<string>(RequestHeaders.Syntax, header.Value);
var headerValue = await expressionEvaluator.EvaluateAsync(
headerValueExpression,
workflowContext,
cancellationToken
);
headers.Add(header.Key, headerValue);
}
}
return headers;
}
private bool GetMethodSupportsBody(string method)
{
var methods = new[] { "POST", "PUT", "PATCH" };
return methods.Contains(method, StringComparer.InvariantCultureIgnoreCase);
}
}
}

View file

@ -1,153 +1,155 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Expressions;
using Elsa.Extensions;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.AspNetCore.Http;
namespace Elsa.Activities.Http.Activities
{
[ActivityDefinition(
Category = "HTTP",
DisplayName = "Send HTTP Response",
Description = "Send an HTTP response.",
RuntimeDescription = "x => !!x.state.statusCode ? `Send an HTTP <strong>${ x.state.statusCode }</strong> - <strong>${ x.state.contentType }</strong> response` : x.definition.description",
Outcomes = new[] { OutcomeNames.Done }
)]
public class HttpResponseAction : Activity
{
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
private readonly IHttpContextAccessor httpContextAccessor;
public static IEnumerable<SelectItem> GetStatusCodes()
{
return new[]
{
new SelectItem
{
Label = "2xx",
Options = new object[] { 200, 201, 202, 203, 204 }
},
new SelectItem
{
Label = "3xx",
Options = new object[] { 301, 302, 304, 307, 308 }
},
new SelectItem
{
Label = "4xx",
Options = new object[] { 400, 401, 402, 403, 404, 405, 409, 410, 412, 413, 415, 417, 418, 420, 428, 429 }
}
};
}
public HttpResponseAction(IWorkflowExpressionEvaluator expressionEvaluator,
IHttpContextAccessor httpContextAccessor)
{
this.expressionEvaluator = expressionEvaluator;
this.httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// The HTTP status code to return.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP status code to write."
)]
[SelectOptions(nameof(GetStatusCodes), typeof(HttpResponseAction))]
public HttpStatusCode StatusCode
{
get => GetState(() => HttpStatusCode.OK);
set => SetState(value);
}
/// <summary>
/// The content to send along with the response
/// </summary>
[ActivityProperty(Hint = "The HTTP content to write.")]
[ExpressionOptions(Multiline = true)]
public WorkflowExpression<string> Content
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
/// <summary>
/// The Content-Type header to send along with the response.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP content type header to write."
)]
[SelectOptions("text/plain", "text/html", "application/json", "application/xml")]
public string ContentType
{
get => GetState<string>();
set => SetState(value);
}
/// <summary>
/// The headers to send along with the response. One 'header: value' pair per line.
/// </summary>
[ActivityProperty(Hint = "The headers to send along with the response. One 'header: value' pair per line.")]
public WorkflowExpression<string> ResponseHeaders
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var response = httpContextAccessor.HttpContext.Response;
if (response.HasStarted)
return Fault("Response has already started");
response.StatusCode = (int) StatusCode;
response.ContentType = ContentType;
var headersText = await expressionEvaluator.EvaluateAsync(
ResponseHeaders,
workflowContext,
cancellationToken
);
if (headersText != null)
{
var headersQuery =
from line in Regex.Split(headersText, "\\n", RegexOptions.Multiline)
let pair = line.Split(':', '=')
select new KeyValuePair<string, string>(pair[0], pair[1]);
foreach (var header in headersQuery)
{
var headerValueExpression = new WorkflowExpression<string>(ResponseHeaders.Syntax, header.Value);
response.Headers[header.Key] = await expressionEvaluator.EvaluateAsync(
headerValueExpression,
workflowContext,
cancellationToken
);
}
}
var bodyText = await expressionEvaluator.EvaluateAsync(Content, workflowContext, cancellationToken);
if (!string.IsNullOrWhiteSpace(bodyText))
{
await response.WriteAsync(bodyText, cancellationToken);
}
return Done();
}
}
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Attributes;
using Elsa.Design;
using Elsa.Expressions;
using Elsa.Extensions;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.AspNetCore.Http;
namespace Elsa.Activities.Http.Activities
{
[ActivityDefinition(
Category = "HTTP",
DisplayName = "Write HTTP Response",
Description = "Write an HTTP response.",
RuntimeDescription = "x => !!x.state.statusCode ? `Send an HTTP <strong>${ x.state.statusCode }</strong> - <strong>${ x.state.contentType }</strong> response` : x.definition.description",
Outcomes = new[] { OutcomeNames.Done }
)]
public class WriteHttpResponse : Activity
{
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
private readonly IHttpContextAccessor httpContextAccessor;
public static IEnumerable<SelectItem> GetStatusCodes()
{
return new[]
{
new SelectItem
{
Label = "2xx",
Options = new object[] { 200, 201, 202, 203, 204 }
},
new SelectItem
{
Label = "3xx",
Options = new object[] { 301, 302, 304, 307, 308 }
},
new SelectItem
{
Label = "4xx",
Options = new object[] { 400, 401, 402, 403, 404, 405, 409, 410, 412, 413, 415, 417, 418, 420, 428, 429 }
}
};
}
public WriteHttpResponse(
IWorkflowExpressionEvaluator expressionEvaluator,
IHttpContextAccessor httpContextAccessor)
{
this.expressionEvaluator = expressionEvaluator;
this.httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// The HTTP status code to return.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP status code to write."
)]
[SelectOptions(nameof(GetStatusCodes), typeof(WriteHttpResponse))]
public HttpStatusCode StatusCode
{
get => GetState(() => HttpStatusCode.OK);
set => SetState(value);
}
/// <summary>
/// The content to send along with the response
/// </summary>
[ActivityProperty(Hint = "The HTTP content to write.")]
[ExpressionOptions(Multiline = true)]
public WorkflowExpression<string> Content
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
/// <summary>
/// The Content-Type header to send along with the response.
/// </summary>
[ActivityProperty(
Type = ActivityPropertyTypes.Select,
Hint = "The HTTP content type header to write."
)]
[SelectOptions("text/plain", "text/html", "application/json", "application/xml")]
public string ContentType
{
get => GetState<string>();
set => SetState(value);
}
/// <summary>
/// The headers to send along with the response. One 'header: value' pair per line.
/// </summary>
[ActivityProperty(Hint = "The headers to send along with the response. One 'header: value' pair per line.")]
public WorkflowExpression<string> ResponseHeaders
{
get => GetState(() => new WorkflowExpression<string>(LiteralEvaluator.SyntaxName, ""));
set => SetState(value);
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
WorkflowExecutionContext workflowContext,
CancellationToken cancellationToken)
{
var response = httpContextAccessor.HttpContext.Response;
if (response.HasStarted)
return Fault("Response has already started");
response.StatusCode = (int)StatusCode;
response.ContentType = ContentType;
var headersText = await expressionEvaluator.EvaluateAsync(
ResponseHeaders,
workflowContext,
cancellationToken
);
if (headersText != null)
{
var headersQuery =
from line in Regex.Split(headersText, "\\n", RegexOptions.Multiline)
let pair = line.Split(':', '=')
select new KeyValuePair<string, string>(pair[0], pair[1]);
foreach (var header in headersQuery)
{
var headerValueExpression = new WorkflowExpression<string>(ResponseHeaders.Syntax, header.Value);
response.Headers[header.Key] = await expressionEvaluator.EvaluateAsync(
headerValueExpression,
workflowContext,
cancellationToken
);
}
}
var bodyText = await expressionEvaluator.EvaluateAsync(Content, workflowContext, cancellationToken);
if (!string.IsNullOrWhiteSpace(bodyText))
{
await response.WriteAsync(bodyText, cancellationToken);
}
return Done();
}
}
}

View file

@ -19,14 +19,14 @@ namespace Elsa.Activities.Http.Controllers
public HttpWorkflowsController(
ITokenService tokenService,
IWorkflowInvoker workflowInvoker,
IWorkflowInvoker workflowInvoker,
IWorkflowInstanceStore workflowInstanceStore)
{
this.tokenService = tokenService;
this.workflowInvoker = workflowInvoker;
this.workflowInstanceStore = workflowInstanceStore;
}
[Route("trigger/{token}")]
[HttpGet, HttpPost]
public async Task<IActionResult> Trigger(string token, CancellationToken cancellationToken)
@ -37,8 +37,8 @@ namespace Elsa.Activities.Http.Controllers
var workflowInstance = await workflowInstanceStore.GetByIdAsync(signal.WorkflowInstanceId, cancellationToken);
if (workflowInstance == null)
return NotFound();
return NotFound();
var input = new Variables
{
["signal"] = signal.Name
@ -46,8 +46,8 @@ namespace Elsa.Activities.Http.Controllers
await workflowInvoker.ResumeAsync(workflowInstance, input, cancellationToken: cancellationToken);
return HttpContext.Items.ContainsKey(WorkflowHttpResult.Instance)
? (IActionResult) new EmptyResult()
return HttpContext.Items.ContainsKey(WorkflowHttpResult.Instance)
? (IActionResult)new EmptyResult()
: Accepted();
}
}

View file

@ -4,13 +4,20 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following Console activities:
* ReceiveHttpRequest
* SendHttpRequest
* WriteHttpResponse
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
<PackageTags>elsa, workflows, http</PackageTags>
</PropertyGroup>
<ItemGroup>
@ -28,4 +35,4 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="3.0.0" />
</ItemGroup>
</Project>
</Project>

View file

@ -13,12 +13,12 @@ namespace Elsa.Activities.Http.Extensions
.UseRequestHandler<TriggerRequestHandler>()
.UseRequestHandler<SignalRequestHandler>("/workflows/signal");
}
public static IApplicationBuilder UseRequestHandler<THandler>(this IApplicationBuilder app) where THandler : IRequestHandler
{
return app.UseMiddleware<RequestHandlerMiddleware<THandler>>();
}
public static IApplicationBuilder UseRequestHandler<THandler>(this IApplicationBuilder app, string path) where THandler : IRequestHandler
{
return app

View file

@ -24,12 +24,12 @@ namespace Elsa.Activities.Http.Extensions
options?.Invoke(services.AddOptions<HttpActivityOptions>());
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddHttpClient(nameof(HttpRequestAction));
services.AddHttpClient(nameof(SendHttpRequest));
services
.AddActivity<HttpRequestEvent>()
.AddActivity<HttpResponseAction>()
.AddActivity<HttpRequestAction>();
.AddActivity<ReceiveHttpRequest>()
.AddActivity<WriteHttpResponse>()
.AddActivity<SendHttpRequest>();
services
.AddSingleton<ITokenService, TokenService>()

View file

@ -10,7 +10,7 @@ namespace Elsa.Activities.Http.Extensions
{
using (var ms = new MemoryStream())
{
await input.CopyToAsync(ms, 16*1024, cancellationToken);
await input.CopyToAsync(ms, 16 * 1024, cancellationToken);
return ms.ToArray();
}
}

View file

@ -25,25 +25,25 @@ namespace Elsa.Activities.Http.Handlers
this.absoluteUrlProvider = absoluteUrlProvider;
this.httpContextAccessor = httpContextAccessor;
}
public Task Handle(EvaluatingJavaScriptExpression notification, CancellationToken cancellationToken)
{
var engine = notification.Engine;
var workflowExecutionContext = notification.WorkflowExecutionContext;
engine.SetValue(
"queryString",
(Func<string, string>) (key => httpContextAccessor.HttpContext.Request.Query[key].ToString())
(Func<string, string>)(key => httpContextAccessor.HttpContext.Request.Query[key].ToString())
);
engine.SetValue(
"absoluteUrl",
(Func<string, string>) (url => absoluteUrlProvider.ToAbsoluteUrl(url).ToString())
(Func<string, string>)(url => absoluteUrlProvider.ToAbsoluteUrl(url).ToString())
);
engine.SetValue(
"signalUrl",
(Func<string, string>) (signal => GenerateUrl(signal, workflowExecutionContext))
(Func<string, string>)(signal => GenerateUrl(signal, workflowExecutionContext))
);
return Task.CompletedTask;
}

View file

@ -14,7 +14,7 @@ namespace Elsa.Activities.Http.Handlers
var context = notification.TemplateContext;
context.MemberAccessStrategy.Register<HttpRequestModel>();
return Task.CompletedTask;
}
}

View file

@ -12,12 +12,12 @@ namespace Elsa.Activities.Http.Middleware
{
this.next = next;
}
public async Task InvokeAsync(HttpContext httpContext, THandler handler)
{
var result = await handler.HandleRequestAsync();
if(result != null && !httpContext.Response.HasStarted)
if (result != null && !httpContext.Response.HasStarted)
await result.ExecuteResultAsync(httpContext, next);
}
}

View file

@ -103,7 +103,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers
workflowInstance.DefinitionId,
VersionOptions.SpecificVersion(workflowInstance.Version),
cancellationToken);
var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, workflowInstance);
var blockingSignalActivities = workflow.BlockingActivities.ToList();
await workflowInvoker.ResumeAsync(workflow, blockingSignalActivities, cancellationToken);

View file

@ -41,11 +41,11 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers
// TODO: Optimize this by building up a hash of routes and workflows to execute.
var requestPath = new Uri(httpContext.Request.Path.ToString(), UriKind.Relative);
var method = httpContext.Request.Method;
var httpWorkflows = await registry.ListByStartActivityAsync(nameof(HttpRequestEvent), cancellationToken);
var httpWorkflows = await registry.ListByStartActivityAsync(nameof(ReceiveHttpRequest), cancellationToken);
var workflowsToStart = Filter(httpWorkflows, requestPath, method).ToList();
var haltedHttpWorkflows = await workflowInstanceStore.ListByBlockingActivityAsync<HttpRequestEvent>(
var haltedHttpWorkflows = await workflowInstanceStore.ListByBlockingActivityAsync<ReceiveHttpRequest>(
cancellationToken: cancellationToken);
var workflowsToResume = Filter(haltedHttpWorkflows, requestPath, method).ToList();
if (!workflowsToStart.Any() && !workflowsToResume.Any())
@ -77,8 +77,8 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers
private bool IsMatch(JObject state, Uri path, string method)
{
var m = HttpRequestEvent.GetMethod(state);
var p = HttpRequestEvent.GetPath(state);
var m = ReceiveHttpRequest.GetMethod(state);
var p = ReceiveHttpRequest.GetPath(state);
return (string.IsNullOrWhiteSpace(m) || m == method) && p == path;
}

View file

@ -9,7 +9,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Results
{
public Task ExecuteResultAsync(HttpContext httpContext, RequestDelegate next)
{
httpContext.Response.StatusCode = (int) HttpStatusCode.Accepted;
httpContext.Response.StatusCode = (int)HttpStatusCode.Accepted;
return Task.CompletedTask;
}
}

View file

@ -9,7 +9,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Results
{
public Task ExecuteResultAsync(HttpContext httpContext, RequestDelegate next)
{
httpContext.Response.StatusCode = (int) HttpStatusCode.BadRequest;
httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Task.CompletedTask;
}
}

View file

@ -9,7 +9,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Results
{
public Task ExecuteResultAsync(HttpContext httpContext, RequestDelegate next)
{
httpContext.Response.StatusCode = (int) HttpStatusCode.NotFound;
httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
return Task.CompletedTask;
}
}

View file

@ -11,7 +11,8 @@ namespace Elsa.Activities.Http.Services
private readonly IHttpContextAccessor httpContextAccessor;
private readonly IOptions<HttpActivityOptions> options;
public DefaultAbsoluteUrlProvider(IHttpContextAccessor httpContextAccessor,
public DefaultAbsoluteUrlProvider(
IHttpContextAccessor httpContextAccessor,
IOptions<HttpActivityOptions> options)
{
this.httpContextAccessor = httpContextAccessor;

View file

@ -11,7 +11,7 @@ namespace Elsa.Activities.Http.Services
{
dataProtector = dataProtectionProvider.CreateProtector("HTTP Workflow Tokens");
}
public string CreateToken<T>(T payload)
{
var json = JsonConvert.SerializeObject(payload);
@ -36,7 +36,6 @@ namespace Elsa.Activities.Http.Services
}
return false;
}
}
}

View file

@ -4,13 +4,19 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following MassTransit activities:
* ReceiveMassTransitMessage
* SendMassTransitMessage
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
<PackageTags>elsa, workflows</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,13 +4,20 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following Timer activities:
* CronEvent
* InstantEvent
* TimerEvent
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
<PackageTags>elsa, workflows, timers, background tasks</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,13 +4,18 @@
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following User Task activities:
* UserTask
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
<PackageTags>elsa, workflows</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -20,12 +20,12 @@ namespace Elsa.Activities.Workflows.Activities
Description = "Trigger the specified signal.",
Icon = "fas fa-broadcast-tower"
)]
public class Trigger : Activity
public class TriggerSignal : Activity
{
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
private readonly IWorkflowInvoker workflowInvoker;
public Trigger(IWorkflowExpressionEvaluator expressionEvaluator, IWorkflowInvoker workflowInvoker)
public TriggerSignal(IWorkflowExpressionEvaluator expressionEvaluator, IWorkflowInvoker workflowInvoker)
{
this.expressionEvaluator = expressionEvaluator;
this.workflowInvoker = workflowInvoker;

View file

@ -2,11 +2,30 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<LangVersion>latest</LangVersion>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the following Workflow activities:
* Correlate
* Finish
* Signaled
* Start
* TriggerSignal
* TriggerWorkflow
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
<ProjectReference Include="..\..\scripting\Elsa.Scripting.JavaScript\Elsa.Scripting.JavaScript.csproj" />
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
<ProjectReference Include="..\..\scripting\Elsa.Scripting.JavaScript\Elsa.Scripting.JavaScript.csproj" />
</ItemGroup>
</Project>

View file

@ -11,7 +11,7 @@ namespace Elsa.Activities.Workflows.Extensions
.AddActivity<TriggerWorkflow>()
.AddActivity<Correlate>()
.AddActivity<Signaled>()
.AddActivity<Trigger>()
.AddActivity<TriggerSignal>()
.AddActivity<Start>()
.AddActivity<Finish>();
}

View file

@ -5,8 +5,11 @@
<RootNamespace>Elsa</RootNamespace>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides abstractions and models that are used by Elsa.Core and other related packages. You don't need to reference this package separately if you reference any other Elsa package.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>

View file

@ -5,8 +5,12 @@
<LangVersion>8</LangVersion>
<RootNamespace>Elsa</RootNamespace>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package contains the heart and soul of what makes Elsa tick. It implements most of the abstractions defined in Elsa.Abstractions.
If you reference the Elsa package, which is recommended, you don;t have to explicitly reference this package.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>

View file

@ -4,8 +4,11 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package references some of the most commonly used packages you are likely to use when working with Elsa.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>

View file

@ -6,8 +6,11 @@
<LangVersion>8</LangVersion>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides the Elsa Dashboard in the form of an MVC Area that you can use in your own ASP.NET Core MVC application.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>

View file

@ -5,8 +5,11 @@
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides a reusable WorkflowDesigner View Component. It is used by Elsa.Dashboard to display the workflow designer.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>

View file

@ -1,18 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>latest</LangVersion>
<PackageVersion>1.0.0</PackageVersion>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<PackageVersion>1.0.0</PackageVersion>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides a CosmosDb persistence provider.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, cosmosdb</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.8.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.8.1"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj"/>
</ItemGroup>
</Project>

View file

@ -5,13 +5,16 @@
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides an Entity Framework Core persistence provider.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows</PackageTags>
<PackageTags>elsa, workflows, entity framework core</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,13 +4,16 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides a MongoDB persistence provider.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows</PackageTags>
<PackageTags>elsa, workflows, mongodb</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,13 +4,16 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides a YesSQL persistence provider.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows</PackageTags>
<PackageTags>elsa, workflows, yessql</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -12,10 +12,10 @@ namespace Sample06
public void Build(IWorkflowBuilder builder)
{
builder
.StartWith<HttpRequestEvent>(
.StartWith<ReceiveHttpRequest>(
activity => activity.Path = new Uri("/hello-world", UriKind.Relative)
)
.Then<HttpResponseAction>(
.Then<WriteHttpResponse>(
activity =>
{
activity.Content = new LiteralExpression("<h1>Hello World!</h1><p>Elsa says hi :)</p>");

View file

@ -22,7 +22,7 @@ namespace Sample07
public void Build(IWorkflowBuilder builder)
{
builder
.StartWith<HttpRequestEvent>(
.StartWith<ReceiveHttpRequest>(
x =>
{
x.Method = HttpMethod.Post.Method;
@ -50,7 +50,7 @@ namespace Sample07
);
}
)
.Then<HttpResponseAction>(
.Then<WriteHttpResponse>(
x =>
{
x.Content = new LiteralExpression(

View file

@ -20,7 +20,7 @@ namespace Sample08.Workflows
public void Build(IWorkflowBuilder builder)
{
builder
.StartWith<HttpRequestEvent>(
.StartWith<ReceiveHttpRequest>(
activity =>
{
activity.Method = HttpMethod.Post.Method;
@ -47,7 +47,7 @@ namespace Sample08.Workflows
{
fork
.When("Write-Response")
.Then<HttpResponseAction>(
.Then<WriteHttpResponse>(
activity =>
{
activity.Content = new LiteralExpression("<h1>Order Received</h1><p>Your order has been received. Waiting for shipment.</p>");

View file

@ -4,13 +4,16 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides a JavaScript expression evaluator based on Jint.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows</PackageTags>
<PackageTags>elsa, workflows, javascript, jint</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,13 +4,16 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides a Liquid expression evaluator based on Fluid.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows</PackageTags>
<PackageTags>elsa, workflows, liquid, fluid</PackageTags>
</PropertyGroup>
<ItemGroup>

View file

@ -4,8 +4,11 @@
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<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>
<Authors>Elsa Contributors</Authors>
<Description>
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
This package provides extension methods that simplify registration of AutoMapper and profiles.
</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>