2023-12-31 09:11:47 +00:00
using System.Runtime.CompilerServices ;
using System.Text.Json ;
using Elsa.Expressions.Models ;
using Elsa.Extensions ;
using Elsa.Http.Bookmarks ;
Support for Writing Custom Trigger Activities Using Existing Trigger Infrastructure (#6527)
* Refactor bookmark naming to use "Name" instead of "ActivityTypeName".
Replaces usages of "ActivityTypeName" with "Name" across relevant classes, filters, and database mappings for clarity and consistency. Maintains backward compatibility where necessary and updates corresponding indices, filters, and methods for proper functionality.
* Add migration for V3_5 with schema updates for EF Core
This migration modifies the `Triggers` and `Bookmarks` tables by adding the `Name` column, updating its nullable state, and creating corresponding indexes. Changes apply to both SQLite and MySQL contexts, ensuring compatibility across databases.
* Refactor bookmark filtering and tenant events handling.
Unified the bookmark filtering logic with overloads that accept multiple names, improving flexibility and reusability. Simplified object initializations in tenant events to enhance code readability and reduce verbosity. Added task continuation logic to background task execution for better task sequencing and error handling.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
* Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
* Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
* Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
* Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
* Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
* Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
* Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Move HttpEndpointOptions model to its own file
The HttpEndpointOptions class was moved from an extension file to its own dedicated file for better organization and modularity. This model defines HTTP endpoint properties such as path, methods, authorization, policies, request timeout, and size limit. The change improves code clarity and structure.
* Fix unnecessary whitespace in Timer.cs
Removed an extra whitespace line in the Timer.cs file to maintain code formatting consistency. No functional changes were made to the code.
* Remove extraneous whitespace in IStimulusSender.cs file
Eliminate unnecessary blank line in the IStimulusSender interface for improved code cleanliness. This change enhances readability and aligns with coding standards.
2025-03-21 22:16:56 +00:00
using Elsa.Http.Extensions ;
2023-12-31 09:11:47 +00:00
using Elsa.Http.UIHints ;
using Elsa.Workflows ;
using Elsa.Workflows.Attributes ;
using Elsa.Workflows.UIHints ;
using Elsa.Workflows.Models ;
using Microsoft.AspNetCore.Http ;
using Microsoft.AspNetCore.Routing ;
using Microsoft.Extensions.DependencyInjection ;
namespace Elsa.Http ;
/// <summary>
/// Wait for an inbound HTTP request that matches the specified path and methods.
/// </summary>
[Activity("Elsa", "HTTP", "Wait for an inbound HTTP request that matches the specified path and methods.", DisplayName = "HTTP Endpoint")]
[Output(IsSerializable = false)]
public class HttpEndpoint : Trigger < HttpRequest >
{
internal const string HttpContextInputKey = "HttpContext" ;
2025-01-15 10:17:21 +00:00
internal const string PathInputKey = "Path" ;
2023-12-31 09:11:47 +00:00
/// <inheritdoc />
2025-01-15 10:17:21 +00:00
public HttpEndpoint ( [ CallerFilePath ] string? source = null , [ CallerLineNumber ] int? line = null ) : base ( source , line )
2023-12-31 09:11:47 +00:00
{
}
/// <summary>
/// The path to associate with the workflow.
/// </summary>
[ Input (
Description = "The path to associate with the workflow." ,
UIHint = InputUIHints . SingleLine ,
UIHandler = typeof ( HttpEndpointPathUIHandler )
) ]
2025-01-15 10:17:21 +00:00
public Input < string > Path { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The HTTP methods to accept.
/// </summary>
[ Input (
Description = "The HTTP methods to accept." ,
Options = new [ ] { "GET" , "POST" , "PUT" , "HEAD" , "DELETE" } ,
UIHint = InputUIHints . CheckList ) ]
public Input < ICollection < string > > SupportedMethods { get ; set ; } = new ( ObjectLiteral . From ( new [ ] { HttpMethods . Get } ) ) ;
/// <summary>
/// Allow authenticated requests only.
/// </summary>
[Input(Description = "Allow authenticated requests only.", Category = "Security")]
public Input < bool > Authorize { get ; set ; } = new ( false ) ;
/// <summary>
/// Provide a policy to evaluate. If the policy fails, the request is forbidden.
/// </summary>
[Input(Description = "Provide a policy to evaluate. If the policy fails, the request is forbidden.", Category = "Security")]
public Input < string? > Policy { get ; set ; } = new ( default ( string? ) ) ;
/// <summary>
/// The maximum time allowed to process the request.
/// </summary>
[Input(Description = "The maximum time allowed to process the request.", Category = "Upload")]
2025-01-15 10:17:21 +00:00
public Input < TimeSpan ? > RequestTimeout { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The maximum request size allowed in bytes.
/// </summary>
[Input(Description = "The maximum request size allowed in bytes.", Category = "Upload")]
2025-01-15 10:17:21 +00:00
public Input < long? > RequestSizeLimit { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The maximum request size allowed in bytes.
/// </summary>
[Input(Description = "The maximum file size allowed in bytes for an individual file.", Category = "Upload")]
2025-01-15 10:17:21 +00:00
public Input < long? > FileSizeLimit { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The allowed file extensions,
/// </summary>
[Input(Description = "Only file extensions in this list are allowed. Leave empty to allow all extensions", Category = "Upload", UIHint = InputUIHints.MultiText)]
2025-01-15 10:17:21 +00:00
public Input < ICollection < string > > AllowedFileExtensions { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The allowed file extensions,
/// </summary>
[Input(Description = "File extensions in this list are forbidden. Leave empty to not block any extension.", Category = "Upload", UIHint = InputUIHints.MultiText)]
2025-01-15 10:17:21 +00:00
public Input < ICollection < string > > BlockedFileExtensions { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The allowed file extensions,
/// </summary>
[Input(Description = "Only MIME types in this list are allowed. Leave empty to allow all types", Category = "Upload", UIHint = InputUIHints.MultiText)]
2025-01-15 10:17:21 +00:00
public Input < ICollection < string > > AllowedMimeTypes { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// A value indicating whether to expose the "Request too large" outcome.
/// </summary>
[Input(Description = "A value indicating whether to expose the \"Request too large\" outcome.", Category = "Outcomes")]
public bool ExposeRequestTooLargeOutcome { get ; set ; }
/// <summary>
/// A value indicating whether to expose the "File too large" outcome.
/// </summary>
[Input(Description = "A value indicating whether to expose the \"File too large\" outcome.", Category = "Outcomes")]
public bool ExposeFileTooLargeOutcome { get ; set ; }
/// <summary>
/// A value indicating whether to expose the "Invalid file extension" outcome.
/// </summary>
[Input(Description = "A value indicating whether to expose the \"Invalid file extension\" outcome.", Category = "Outcomes")]
public bool ExposeInvalidFileExtensionOutcome { get ; set ; }
/// <summary>
/// A value indicating whether to expose the "Invalid file MIME type" outcome.
/// </summary>
[Input(Description = "A value indicating whether to expose the \"Invalid file MIME type\" outcome.", Category = "Outcomes")]
public bool ExposeInvalidFileMimeTypeOutcome { get ; set ; }
/// <summary>
/// The parsed request content, if any.
/// </summary>
[Output(Description = "The parsed request content, if any.")]
2025-01-15 10:17:21 +00:00
public Output < object? > ParsedContent { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The uploaded files, if any.
/// </summary>
[Output(Description = "The uploaded files, if any.", IsSerializable = false)]
2025-01-15 10:17:21 +00:00
public Output < IFormFile [ ] > Files { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The parsed route data, if any.
/// </summary>
[Output(Description = "The parsed route data, if any.")]
2025-01-15 10:17:21 +00:00
public Output < IDictionary < string , object > > RouteData { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The querystring data, if any.
/// </summary>
[Output(Description = "The querystring data, if any.")]
2025-01-15 10:17:21 +00:00
public Output < IDictionary < string , object > > QueryStringData { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <summary>
/// The headers, if any.
/// </summary>
[Output(Description = "The headers, if any.")]
2025-01-15 10:17:21 +00:00
public Output < IDictionary < string , object > > Headers { get ; set ; } = null ! ;
2023-12-31 09:11:47 +00:00
/// <inheritdoc />
2025-03-20 11:04:51 +00:00
protected override IEnumerable < object > GetTriggerPayloads ( TriggerIndexingContext context )
{
Support for Writing Custom Trigger Activities Using Existing Trigger Infrastructure (#6527)
* Refactor bookmark naming to use "Name" instead of "ActivityTypeName".
Replaces usages of "ActivityTypeName" with "Name" across relevant classes, filters, and database mappings for clarity and consistency. Maintains backward compatibility where necessary and updates corresponding indices, filters, and methods for proper functionality.
* Add migration for V3_5 with schema updates for EF Core
This migration modifies the `Triggers` and `Bookmarks` tables by adding the `Name` column, updating its nullable state, and creating corresponding indexes. Changes apply to both SQLite and MySQL contexts, ensuring compatibility across databases.
* Refactor bookmark filtering and tenant events handling.
Unified the bookmark filtering logic with overloads that accept multiple names, improving flexibility and reusability. Simplified object initializations in tenant events to enhance code readability and reduce verbosity. Added task continuation logic to background task execution for better task sequencing and error handling.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
* Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
* Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
* Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
* Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
* Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
* Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
* Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Move HttpEndpointOptions model to its own file
The HttpEndpointOptions class was moved from an extension file to its own dedicated file for better organization and modularity. This model defines HTTP endpoint properties such as path, methods, authorization, policies, request timeout, and size limit. The change improves code clarity and structure.
* Fix unnecessary whitespace in Timer.cs
Removed an extra whitespace line in the Timer.cs file to maintain code formatting consistency. No functional changes were made to the code.
* Remove extraneous whitespace in IStimulusSender.cs file
Eliminate unnecessary blank line in the IStimulusSender interface for improved code cleanliness. This change enhances readability and aligns with coding standards.
2025-03-21 22:16:56 +00:00
context . TriggerName = HttpStimulusNames . HttpEndpoint ;
2025-03-20 11:04:51 +00:00
return GetBookmarkPayloads ( context . ExpressionExecutionContext ) ;
}
2023-12-31 09:11:47 +00:00
/// <inheritdoc />
protected override async ValueTask ExecuteAsync ( ActivityExecutionContext context )
{
var path = Path . Get ( context ) ;
Support for Writing Custom Trigger Activities Using Existing Trigger Infrastructure (#6527)
* Refactor bookmark naming to use "Name" instead of "ActivityTypeName".
Replaces usages of "ActivityTypeName" with "Name" across relevant classes, filters, and database mappings for clarity and consistency. Maintains backward compatibility where necessary and updates corresponding indices, filters, and methods for proper functionality.
* Add migration for V3_5 with schema updates for EF Core
This migration modifies the `Triggers` and `Bookmarks` tables by adding the `Name` column, updating its nullable state, and creating corresponding indexes. Changes apply to both SQLite and MySQL contexts, ensuring compatibility across databases.
* Refactor bookmark filtering and tenant events handling.
Unified the bookmark filtering logic with overloads that accept multiple names, improving flexibility and reusability. Simplified object initializations in tenant events to enhance code readability and reduce verbosity. Added task continuation logic to background task execution for better task sequencing and error handling.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
* Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
* Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
* Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
* Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
* Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
* Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
* Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Move HttpEndpointOptions model to its own file
The HttpEndpointOptions class was moved from an extension file to its own dedicated file for better organization and modularity. This model defines HTTP endpoint properties such as path, methods, authorization, policies, request timeout, and size limit. The change improves code clarity and structure.
* Fix unnecessary whitespace in Timer.cs
Removed an extra whitespace line in the Timer.cs file to maintain code formatting consistency. No functional changes were made to the code.
* Remove extraneous whitespace in IStimulusSender.cs file
Eliminate unnecessary blank line in the IStimulusSender interface for improved code cleanliness. This change enhances readability and aligns with coding standards.
2025-03-21 22:16:56 +00:00
var methods = SupportedMethods . GetOrDefault ( context ) ? ? new List < string > { HttpMethods . Get } ;
2025-05-20 09:24:23 +00:00
await context . WaitForHttpRequestAsync ( path , methods , OnResumeAsync ) ;
2023-12-31 09:11:47 +00:00
}
private async ValueTask OnResumeAsync ( ActivityExecutionContext context )
{
var httpContextAccessor = context . GetRequiredService < IHttpContextAccessor > ( ) ;
var httpContext = httpContextAccessor . HttpContext ;
if ( httpContext = = null )
{
// We're executing in a non-HTTP context (e.g. in a virtual actor).
// Create a bookmark to allow the invoker to export the state and resume execution from there.
Support for Writing Custom Trigger Activities Using Existing Trigger Infrastructure (#6527)
* Refactor bookmark naming to use "Name" instead of "ActivityTypeName".
Replaces usages of "ActivityTypeName" with "Name" across relevant classes, filters, and database mappings for clarity and consistency. Maintains backward compatibility where necessary and updates corresponding indices, filters, and methods for proper functionality.
* Add migration for V3_5 with schema updates for EF Core
This migration modifies the `Triggers` and `Bookmarks` tables by adding the `Name` column, updating its nullable state, and creating corresponding indexes. Changes apply to both SQLite and MySQL contexts, ensuring compatibility across databases.
* Refactor bookmark filtering and tenant events handling.
Unified the bookmark filtering logic with overloads that accept multiple names, improving flexibility and reusability. Simplified object initializations in tenant events to enhance code readability and reduce verbosity. Added task continuation logic to background task execution for better task sequencing and error handling.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
* Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
* Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
* Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
* Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
* Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
* Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
* Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Move HttpEndpointOptions model to its own file
The HttpEndpointOptions class was moved from an extension file to its own dedicated file for better organization and modularity. This model defines HTTP endpoint properties such as path, methods, authorization, policies, request timeout, and size limit. The change improves code clarity and structure.
* Fix unnecessary whitespace in Timer.cs
Removed an extra whitespace line in the Timer.cs file to maintain code formatting consistency. No functional changes were made to the code.
* Remove extraneous whitespace in IStimulusSender.cs file
Eliminate unnecessary blank line in the IStimulusSender interface for improved code cleanliness. This change enhances readability and aligns with coding standards.
2025-03-21 22:16:56 +00:00
context . CreateCrossBoundaryBookmark ( ) ;
2023-12-31 09:11:47 +00:00
return ;
}
Support for Writing Custom Trigger Activities Using Existing Trigger Infrastructure (#6527)
* Refactor bookmark naming to use "Name" instead of "ActivityTypeName".
Replaces usages of "ActivityTypeName" with "Name" across relevant classes, filters, and database mappings for clarity and consistency. Maintains backward compatibility where necessary and updates corresponding indices, filters, and methods for proper functionality.
* Add migration for V3_5 with schema updates for EF Core
This migration modifies the `Triggers` and `Bookmarks` tables by adding the `Name` column, updating its nullable state, and creating corresponding indexes. Changes apply to both SQLite and MySQL contexts, ensuring compatibility across databases.
* Refactor bookmark filtering and tenant events handling.
Unified the bookmark filtering logic with overloads that accept multiple names, improving flexibility and reusability. Simplified object initializations in tenant events to enhance code readability and reduce verbosity. Added task continuation logic to background task execution for better task sequencing and error handling.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
* Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
* Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
* Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
* Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
* Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
* Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
* Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Move HttpEndpointOptions model to its own file
The HttpEndpointOptions class was moved from an extension file to its own dedicated file for better organization and modularity. This model defines HTTP endpoint properties such as path, methods, authorization, policies, request timeout, and size limit. The change improves code clarity and structure.
* Fix unnecessary whitespace in Timer.cs
Removed an extra whitespace line in the Timer.cs file to maintain code formatting consistency. No functional changes were made to the code.
* Remove extraneous whitespace in IStimulusSender.cs file
Eliminate unnecessary blank line in the IStimulusSender interface for improved code cleanliness. This change enhances readability and aligns with coding standards.
2025-03-21 22:16:56 +00:00
await HandleRequestAsync ( context ) ;
2023-12-31 09:11:47 +00:00
}
Support for Writing Custom Trigger Activities Using Existing Trigger Infrastructure (#6527)
* Refactor bookmark naming to use "Name" instead of "ActivityTypeName".
Replaces usages of "ActivityTypeName" with "Name" across relevant classes, filters, and database mappings for clarity and consistency. Maintains backward compatibility where necessary and updates corresponding indices, filters, and methods for proper functionality.
* Add migration for V3_5 with schema updates for EF Core
This migration modifies the `Triggers` and `Bookmarks` tables by adding the `Name` column, updating its nullable state, and creating corresponding indexes. Changes apply to both SQLite and MySQL contexts, ensuring compatibility across databases.
* Refactor bookmark filtering and tenant events handling.
Unified the bookmark filtering logic with overloads that accept multiple names, improving flexibility and reusability. Simplified object initializations in tenant events to enhance code readability and reduce verbosity. Added task continuation logic to background task execution for better task sequencing and error handling.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
* Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
* Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
* Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
* Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
* Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
* Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
* Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Move HttpEndpointOptions model to its own file
The HttpEndpointOptions class was moved from an extension file to its own dedicated file for better organization and modularity. This model defines HTTP endpoint properties such as path, methods, authorization, policies, request timeout, and size limit. The change improves code clarity and structure.
* Fix unnecessary whitespace in Timer.cs
Removed an extra whitespace line in the Timer.cs file to maintain code formatting consistency. No functional changes were made to the code.
* Remove extraneous whitespace in IStimulusSender.cs file
Eliminate unnecessary blank line in the IStimulusSender interface for improved code cleanliness. This change enhances readability and aligns with coding standards.
2025-03-21 22:16:56 +00:00
private async Task HandleRequestAsync ( ActivityExecutionContext context )
2023-12-31 09:11:47 +00:00
{
Support for Writing Custom Trigger Activities Using Existing Trigger Infrastructure (#6527)
* Refactor bookmark naming to use "Name" instead of "ActivityTypeName".
Replaces usages of "ActivityTypeName" with "Name" across relevant classes, filters, and database mappings for clarity and consistency. Maintains backward compatibility where necessary and updates corresponding indices, filters, and methods for proper functionality.
* Add migration for V3_5 with schema updates for EF Core
This migration modifies the `Triggers` and `Bookmarks` tables by adding the `Name` column, updating its nullable state, and creating corresponding indexes. Changes apply to both SQLite and MySQL contexts, ensuring compatibility across databases.
* Refactor bookmark filtering and tenant events handling.
Unified the bookmark filtering logic with overloads that accept multiple names, improving flexibility and reusability. Simplified object initializations in tenant events to enhance code readability and reduce verbosity. Added task continuation logic to background task execution for better task sequencing and error handling.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
* Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
* Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
* Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
* Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
* Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
* Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
* Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Refactor bookmark creation to use target-typed `new` expressions.
Replaces explicit `CreateBookmarkArgs` instantiations with concise target-typed `new` expressions for improved readability and reduced redundancy. This does not alter functionality but simplifies the code structure.
Make callback parameters optional and adjust OTEL settings
Updated methods to allow optional callbacks for improved flexibility. Refactored Delay activity to reuse helper methods. Adjusted OTEL instrumentation settings to enable console exporter and disable manual instrumentation.
Refactor stimulus handling and streamline event workflows.
Introduces `WaitForEvent` and `GetEventInput` extensions to improve ActivityExecutionContext usability. Replaces generic filter methods with targeted single-name filtering, simplifying scheduling logic. Updates stimulus names for consistency and deprecates obsolete methods to enhance clarity and maintainability.
Refactor `Event` activity handling and event stimulus logic.
Replaces inline event stimulus creation with a new `GetEventStimulus` helper method for cleaner code. Simplifies event execution handling by removing redundant logic in `ExecuteAsync`. Extends `WaitForEvent` to handle workflow triggers more efficiently.
Refactor and enhance Timer and Delay execution logic
Introduced `TimerBase` for shared timer functionality and refactored `Timer` to extend it. Improved method names for clarity, replacing `ResumeIn`/`ResumeAt` with `DelayFor`/`DelayUntil`. Enhanced flexibility in bookmark handling and activity execution context extensions.
Add custom activities and refactor HTTP stimulus handling
Introduce new custom activities (CustomDelay, CustomEvent, CustomHttpEndpoint, CustomTimer) to enhance workflow functionality. Refactor HTTP stimulus handling by replacing activity type names with a new centralized HttpStimulusNames constant, improving consistency and maintainability. Additionally, streamline HTTP endpoint logic with new helper extensions and simplify related services to reduce redundancy.
Add HttpEndpointBase abstraction to simplify HTTP endpoints
Introduce a new `HttpEndpointBase` class to centralize common logic for HTTP endpoint activities. Refactored `CustomHttpEndpoint` to inherit from this new base class, reducing redundancy and improving maintainability.
Refactor events framework with base class for event activities
Introduce `EventBase` to streamline implementations of event-driven activities. Updated `CustomEvent` to inherit from `EventBase`, reducing duplicate logic and improving maintainability. Removed unnecessary dependencies in `CustomTimer`.
* Move HttpEndpointOptions model to its own file
The HttpEndpointOptions class was moved from an extension file to its own dedicated file for better organization and modularity. This model defines HTTP endpoint properties such as path, methods, authorization, policies, request timeout, and size limit. The change improves code clarity and structure.
* Fix unnecessary whitespace in Timer.cs
Removed an extra whitespace line in the Timer.cs file to maintain code formatting consistency. No functional changes were made to the code.
* Remove extraneous whitespace in IStimulusSender.cs file
Eliminate unnecessary blank line in the IStimulusSender interface for improved code cleanliness. This change enhances readability and aligns with coding standards.
2025-03-21 22:16:56 +00:00
var httpContextAccessor = context . GetRequiredService < IHttpContextAccessor > ( ) ;
var httpContext = httpContextAccessor . HttpContext ! ;
2023-12-31 09:11:47 +00:00
// Provide the received HTTP request as output.
var request = httpContext . Request ;
context . Set ( Result , request ) ;
// Read route data, if any.
2025-01-15 10:17:21 +00:00
var path = context . GetWorkflowInput < PathString > ( PathInputKey ) ;
2023-12-31 09:11:47 +00:00
var routeData = GetRouteData ( httpContext , path ) ;
var routeDictionary = routeData . Values . ToDictionary ( route = > route . Key , route = > route . Value ! ) ;
2024-01-21 09:52:46 +00:00
var queryStringDictionary = httpContext . Request . Query . ToObjectDictionary ( ) ;
var headersDictionary = httpContext . Request . Headers . ToObjectDictionary ( ) ;
2023-12-31 09:11:47 +00:00
context . Set ( RouteData , routeDictionary ) ;
context . Set ( QueryStringData , queryStringDictionary ) ;
context . Set ( Headers , headersDictionary ) ;
// Validate request size.
if ( ! ValidateRequestSize ( context , httpContext ) )
{
await HandleRequestTooLargeAsync ( context , httpContext ) ;
return ;
}
2024-01-21 09:52:46 +00:00
// Handle Form Fields
if ( request . HasFormContentType )
2023-12-31 09:11:47 +00:00
{
2024-01-21 09:52:46 +00:00
var formFields = request . Form . ToObjectDictionary ( ) ;
2023-12-31 09:11:47 +00:00
2024-01-21 09:52:46 +00:00
ParsedContent . Set ( context , formFields ) ;
2023-12-31 09:11:47 +00:00
2024-01-21 09:52:46 +00:00
// Read files, if any.
var files = ReadFilesAsync ( context , request ) ;
if ( files . Any ( ) )
2023-12-31 09:11:47 +00:00
{
2024-01-21 09:52:46 +00:00
if ( ! ValidateFileSizes ( context , httpContext , files ) )
{
await HandleFileSizeTooLargeAsync ( context , httpContext ) ;
return ;
}
if ( ! ValidateFileExtensionWhitelist ( context , httpContext , files ) )
{
await HandleInvalidFileExtensionWhitelistAsync ( context , httpContext ) ;
return ;
}
if ( ! ValidateFileExtensionBlacklist ( context , httpContext , files ) )
{
await HandleInvalidFileExtensionBlacklistAsync ( context , httpContext ) ;
return ;
}
if ( ! ValidateFileMimeTypes ( context , httpContext , files ) )
{
await HandleInvalidFileMimeTypesAsync ( context , httpContext ) ;
return ;
}
Files . Set ( context , files . ToArray ( ) ) ;
2023-12-31 09:11:47 +00:00
}
2024-01-21 09:52:46 +00:00
}
else
{
// Parse Non-Form content.
try
2023-12-31 09:11:47 +00:00
{
2024-01-21 09:52:46 +00:00
var content = await ParseContentAsync ( context , request ) ;
ParsedContent . Set ( context , content ) ;
2023-12-31 09:11:47 +00:00
}
2024-01-21 09:52:46 +00:00
catch ( JsonException e )
2023-12-31 09:11:47 +00:00
{
2024-01-21 09:52:46 +00:00
await HandleInvalidJsonPayloadAsync ( context , httpContext , e ) ;
throw ;
2023-12-31 09:11:47 +00:00
}
}
// Complete.
await context . CompleteActivityAsync ( ) ;
}
private IFormFileCollection ReadFilesAsync ( ActivityExecutionContext context , HttpRequest request )
{
return request . HasFormContentType ? request . Form . Files : new FormFileCollection ( ) ;
}
private bool ValidateRequestSize ( ActivityExecutionContext context , HttpContext httpContext )
{
var requestSizeLimit = RequestSizeLimit . GetOrDefault ( context ) ;
if ( ! requestSizeLimit . HasValue )
return true ;
var requestSize = httpContext . Request . ContentLength ? ? 0 ;
return requestSize < = requestSizeLimit ;
}
private async Task HandleRequestTooLargeAsync ( ActivityExecutionContext context , HttpContext httpContext )
{
var exposeRequestTooLargeOutcome = ExposeRequestTooLargeOutcome ;
if ( exposeRequestTooLargeOutcome )
{
await context . CompleteActivityWithOutcomesAsync ( "Request too large" ) ;
}
else
{
var response = httpContext . Response ;
response . StatusCode = StatusCodes . Status413PayloadTooLarge ;
await response . WriteAsJsonAsync ( new
{
Message = $"The maximum request size allowed is {RequestSizeLimit.Get(context)} bytes."
} ) ;
await response . Body . FlushAsync ( ) ;
}
}
private bool ValidateFileSizes ( ActivityExecutionContext context , HttpContext httpContext , IFormFileCollection files )
{
var fileSizeLimit = FileSizeLimit . GetOrDefault ( context ) ;
if ( ! fileSizeLimit . HasValue )
return true ;
if ( ! files . Any ( file = > file . Length > fileSizeLimit . Value ) )
return true ;
return false ;
}
private async Task HandleFileSizeTooLargeAsync ( ActivityExecutionContext context , HttpContext httpContext )
{
var exposeFileTooLargeOutcome = ExposeFileTooLargeOutcome ;
if ( exposeFileTooLargeOutcome )
{
await context . CompleteActivityWithOutcomesAsync ( "File too large" ) ;
}
else
{
var response = httpContext . Response ;
response . StatusCode = StatusCodes . Status413PayloadTooLarge ;
await response . WriteAsJsonAsync ( new
{
Message = $"The maximum file size allowed is {FileSizeLimit.Get(context)} bytes."
} ) ;
await response . Body . FlushAsync ( ) ;
}
}
private bool ValidateFileExtensionWhitelist ( ActivityExecutionContext context , HttpContext httpContext , IFormFileCollection files )
{
var allowedFileExtensions = AllowedFileExtensions . GetOrDefault ( context ) ;
if ( allowedFileExtensions = = null | | ! allowedFileExtensions . Any ( ) )
return true ;
if ( files . All ( file = > allowedFileExtensions . Contains ( System . IO . Path . GetExtension ( file . FileName ) , StringComparer . OrdinalIgnoreCase ) ) )
return true ;
return false ;
}
private async Task HandleInvalidFileExtensionWhitelistAsync ( ActivityExecutionContext context , HttpContext httpContext )
{
if ( ExposeInvalidFileExtensionOutcome )
{
await context . CompleteActivityWithOutcomesAsync ( "Invalid file extension" ) ;
return ;
}
var response = httpContext . Response ;
var allowedFileExtensions = AllowedFileExtensions . GetOrDefault ( context ) ! ;
response . StatusCode = StatusCodes . Status415UnsupportedMediaType ;
await response . WriteAsJsonAsync ( new
{
Message = $"Only the following file extensions are allowed: {string.Join(" , ", allowedFileExtensions)}"
} ) ;
await response . Body . FlushAsync ( ) ;
}
private bool ValidateFileExtensionBlacklist ( ActivityExecutionContext context , HttpContext httpContext , IFormFileCollection files )
{
var blockedFileExtensions = BlockedFileExtensions . GetOrDefault ( context ) ;
if ( blockedFileExtensions = = null | | ! blockedFileExtensions . Any ( ) )
return true ;
if ( ! files . Any ( file = > blockedFileExtensions . Contains ( System . IO . Path . GetExtension ( file . FileName ) , StringComparer . OrdinalIgnoreCase ) ) )
return true ;
return false ;
}
private async Task HandleInvalidFileExtensionBlacklistAsync ( ActivityExecutionContext context , HttpContext httpContext )
{
if ( ExposeInvalidFileExtensionOutcome )
{
await context . CompleteActivityWithOutcomesAsync ( "Invalid file extension" ) ;
return ;
}
var blockedFileExtensions = BlockedFileExtensions . GetOrDefault ( context ) ! ;
var response = httpContext . Response ;
response . StatusCode = StatusCodes . Status415UnsupportedMediaType ;
await response . WriteAsJsonAsync ( new
{
Message = $"The following file extensions are not allowed: {string.Join(" , ", blockedFileExtensions)}"
} ) ;
await response . Body . FlushAsync ( ) ;
}
private bool ValidateFileMimeTypes ( ActivityExecutionContext context , HttpContext httpContext , IFormFileCollection files )
{
var allowedMimeTypes = AllowedMimeTypes . GetOrDefault ( context ) ;
if ( allowedMimeTypes = = null | | ! allowedMimeTypes . Any ( ) )
return true ;
if ( files . All ( file = > allowedMimeTypes . Contains ( file . ContentType , StringComparer . OrdinalIgnoreCase ) ) )
return true ;
return false ;
}
private async Task HandleInvalidFileMimeTypesAsync ( ActivityExecutionContext context , HttpContext httpContext )
{
if ( ExposeInvalidFileMimeTypeOutcome )
{
await context . CompleteActivityWithOutcomesAsync ( "Invalid file MIME type" ) ;
return ;
}
var allowedMimeTypes = AllowedMimeTypes . GetOrDefault ( context ) ! ;
var response = httpContext . Response ;
response . StatusCode = StatusCodes . Status415UnsupportedMediaType ;
await response . WriteAsJsonAsync ( new
{
Message = $"Only the following MIME types are allowed: {string.Join(" , ", allowedMimeTypes)}"
} ) ;
await response . Body . FlushAsync ( ) ;
}
private async Task HandleInvalidJsonPayloadAsync ( ActivityExecutionContext context , HttpContext httpContext , JsonException exception )
{
var response = httpContext . Response ;
response . StatusCode = StatusCodes . Status400BadRequest ;
await response . WriteAsJsonAsync ( new
{
exception . Message ,
exception . Path ,
exception . LineNumber ,
} ) ;
await response . Body . FlushAsync ( ) ;
}
private async Task < object? > ParseContentAsync ( ActivityExecutionContext context , HttpRequest httpRequest )
{
if ( ! HasContent ( httpRequest ) )
return null ;
var cancellationToken = context . CancellationToken ;
var targetType = ParsedContent . GetTargetType ( context ) ;
var contentStream = httpRequest . Body ;
var contentType = httpRequest . ContentType ! ;
2024-06-13 20:13:53 +00:00
var headers = httpRequest . Headers . ToDictionary ( x = > x . Key , x = > x . Value . ToArray ( ) ) ;
2023-12-31 09:11:47 +00:00
2024-06-13 20:13:53 +00:00
return await context . ParseContentAsync ( contentStream , contentType , targetType , headers , cancellationToken ) ;
2023-12-31 09:11:47 +00:00
}
private static bool HasContent ( HttpRequest httpRequest ) = > httpRequest . Headers . ContentLength > 0 ;
private IEnumerable < object > GetBookmarkPayloads ( ExpressionExecutionContext context )
{
// Generate bookmark data for path and selected methods.
var normalizedRoute = context . Get ( Path ) ! . NormalizeRoute ( ) ;
var methods = SupportedMethods . GetOrDefault ( context ) ? ? new List < string > { HttpMethods . Get } ;
var authorize = Authorize . GetOrDefault ( context ) ;
var policy = Policy . GetOrDefault ( context ) ;
var requestTimeout = RequestTimeout . GetOrDefault ( context ) ;
var requestSizeLimit = RequestSizeLimit . GetOrDefault ( context ) ;
return methods
. Select ( x = > new HttpEndpointBookmarkPayload ( normalizedRoute , x . ToLowerInvariant ( ) , authorize , policy , requestTimeout , requestSizeLimit ) )
. Cast < object > ( )
. ToArray ( ) ;
}
private static RouteData GetRouteData ( HttpContext httpContext , string path )
{
var routeData = httpContext . GetRouteData ( ) ;
var routeTable = httpContext . RequestServices . GetRequiredService < IRouteTable > ( ) ;
var routeMatcher = httpContext . RequestServices . GetRequiredService < IRouteMatcher > ( ) ;
var matchingRouteQuery =
from route in routeTable
2024-10-14 19:27:11 +00:00
let routeValues = routeMatcher . Match ( route . Route , path )
2023-12-31 09:11:47 +00:00
where routeValues ! = null
select new { route , routeValues } ;
var matchingRoute = matchingRouteQuery . FirstOrDefault ( ) ;
if ( matchingRoute = = null )
return routeData ;
foreach ( var ( key , value ) in matchingRoute . routeValues ! )
routeData . Values [ key ] = value ;
return routeData ;
}
2025-05-20 09:24:23 +00:00
}