2023-08-06 18:55:24 +00:00
|
|
|
using System.Runtime.CompilerServices;
|
Add a more generic UIHandler to customize how inputAttributes can be handle by UI (#4688)
* add a more generic UIHandler to customize how inputAttributes can be handle by the ui
* Add IPropertyUIHandlerResolver and update PropertyUIHandlerResolver
Introduced a new interface, IPropertyUIHandlerResolver, to resolve UI options for a property. Refactored PropertyUIHandlerResolver to implement this interface and removed the unnecessary partial class structure. Also, cleaned up some unnecessary usings in various files for better code organization.
* Refactor variable name and description in InputDescriptor
The 'uISpecifications' variable in the InputDescriptor model is renamed to 'uiSpecifications' for better readability. Additionally, the associated comment was revised to explain that the dictionary is used by the UI.
* "Refactor codebase for improved organization and cleaner architecture"
The codebase has been significantly refactored, moving several classes to more appropriate namespaces for improved organization and cleaner architecture. This includes shifting UI hint handlers, activities, and memory-related components, amongst others. The changes should improve code readability and maintainability, but as this is a broad refactoring effort, thorough regression testing is advised.
* Add CheckList UIHint with associated handler and provider
This update introduces a new UIHint called CheckList to the Elsa.Workflows.Core. This includes the necessary handler and provider classes. The handler is registered in the WorkflowsFeature.cs, and the CheckList UIHint key has been added to the InputUIHints.cs. Various associated files have been created in both the Elsa.Api.Client and Elsa.Workflows.Core project to support this new UIHint.
---------
Co-authored-by: Jérémie DEVILLARD <jdevillard@users.noreply.github.com>
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
2023-12-26 17:56:29 +00:00
|
|
|
using Elsa.Workflows;
|
|
|
|
|
using Elsa.Workflows.Attributes;
|
2022-10-25 13:52:55 +00:00
|
|
|
|
|
|
|
|
namespace Elsa.Http;
|
|
|
|
|
|
2023-03-07 12:45:58 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Send an HTTP request.
|
|
|
|
|
/// </summary>
|
2023-08-06 18:55:24 +00:00
|
|
|
[Activity("Elsa", "HTTP", "Send an HTTP request.", DisplayName = "HTTP Request", Kind = ActivityKind.Task)]
|
|
|
|
|
public class SendHttpRequest : SendHttpRequestBase
|
2023-03-07 12:45:58 +00:00
|
|
|
{
|
|
|
|
|
/// <inheritdoc />
|
Add IResilienceStrategy Abstraction with Category Matching and Expression-Based Configuration (#6637)
* Add resilience module with core interfaces and services
Introduced a new `Elsa.Resilience` module and its core components to support resilient services and activities. This includes resilience strategies, providers, and attributes, along with integration into the existing HTTP module for enhanced fault tolerance. Added solution and project references for proper dependency management.
* Add resilience strategy framework with HTTP strategy support
Introduced a resilience strategy architecture, including a configurable `HttpResilienceStrategy` with retry capabilities, strategy serialization, and integration with existing modules. Enhanced ResilienceFeature to support registration of strategy types and updated application configuration to enable resilience strategies. This change ensures more robust and fault-tolerant HTTP request handling.
* Add JSON serialization support for resilience configuration
Introduced `ConfigurationExtensions` to enable JSON serialization of configuration sections. Updated resilience strategies to utilize the new extension methods and adjusted JSON serialization logic to support polymorphism with `$type` discriminator. Minor modifications were made to support deserialization and property mutability.
* Add resilience strategy support to workflows and API clients
Introduced resilience strategy configuration, serialization, and execution support across workflows and API clients. Added new APIs, models, and services to enhance fault tolerance capabilities for activities and HTTP interactions.
* Refactor resilience services for improved modularity.
Replaced `IResilienceService` with new modular interfaces (`IResilienceStrategyCatalog`, `IResilienceStrategyConfigEvaluator`, `IResilientActivityInvoker`) and corresponding implementations. Enhanced maintainability by simplifying components and responsibilities, ensuring better separation of concerns.
* Rename methods in ResilienceStrategyCatalog for clarity
Updated method names in `ResilienceStrategyCatalog` and its interfaces for better readability and alignment with naming conventions. Replaced `GetAllStrategiesAsync` with `ListAsync` and `GetStrategyAsync` with `GetAsync` across the codebase.
* Refactor resilience handling in HTTP activities.
Replaced `ResilienceCategory` property with `ResilienceCategoryAttribute` for a cleaner implementation. Updated `IResilientActivity` to simplify its interface and adjusted related modifications accordingly. Introduced `IResilientActivityInvoker` to enhance resilience strategy execution.
* Add support for additional resilience and scripting features
Extended resilience strategy handling with serialization support, added `HttpResilienceStrategy` type in JavaScript handler, and refined object conversion logic for interfaces. Minor adjustments to `Expression` class properties for consistency.
* Remove `UseResilience` call from Program.cs
This call was redundant and no longer necessary for the application. Its removal simplifies the code and ensures only required middleware is used.
* Remove commented-out JSON converter code in serializer setup
Cleaned up unused and commented-out converter initialization code in `ResilienceStrategySerializer`. This improves readability and removes unnecessary clutter from the file.
* Fix typo in method names from 'Resiliency' to 'Resilience'
Renamed methods to maintain consistency in naming conventions across the codebase. This change ensures clarity and alignment with established terminology.
* Refactor namespace for ConfigurationResilienceStrategySource
Updated the namespace of ConfigurationResilienceStrategySource to "StrategySources" for better alignment with naming conventions and structure. Removed an unused namespace reference in ResilienceFeature for cleanup.
* Mark EnableResiliency as obsolete in SendHttpRequestBase.
The EnableResiliency property is now marked with the [Obsolete] attribute. Developers are encouraged to use the common Resilience Strategy setting instead for managing HTTP request resiliency. This change ensures better consistency and alignment with the broader resilience strategy.
* Restrict ResilienceCategoryAttribute to class targets only
Removed support for using ResilienceCategoryAttribute on properties. This change enforces a stricter and more focused usage of the attribute, ensuring it applies only to class-level declarations.
* Add documentation for IResilientActivityInvoker interface
Include summaries and parameter descriptions for the `InvokeAsync` method. This improves code clarity and helps developers understand the functionality and usage of the resilient activity invocation process.
* Fix logical operator precedence in type comparison check
Parentheses were added to ensure correct evaluation of conditions when checking type compatibility. This prevents potential logical errors when determining the target type in object conversions.
* Add support for resilience source identification
Introduce the `ResilienceSourceNameAttribute` to allow naming of resilience sources. Updated `ResilienceStrategyCatalog` to utilize the attribute for prefixing strategy IDs, improving source identification and traceability. Applied the attribute to `ConfigurationResilienceStrategySource` as an example.
* Revert "Add support for resilience source identification"
This reverts commit 19b4e7121d6330b5de4f692b78da4c1e4a2d1f67.
* Reapply "Add support for resilience source identification"
This reverts commit 8bcba9d040c4eb247077aec6d90dc02817adcbd5.
* Revert "Reapply "Add support for resilience source identification""
This reverts commit ee04d35e7930956c752dda3ed150ca34a535e66c.
2025-05-12 08:09:04 +00:00
|
|
|
public SendHttpRequest([CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : base(source, line)
|
2023-03-07 12:45:58 +00:00
|
|
|
{
|
|
|
|
|
}
|
2023-08-25 23:11:10 +00:00
|
|
|
|
2023-03-07 12:45:58 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// A list of expected status codes to handle and the corresponding activity to execute when the status code matches.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Input(
|
|
|
|
|
Description = "A list of expected status codes to handle and the corresponding activity to execute when the status code matches.",
|
2023-03-11 21:14:39 +00:00
|
|
|
UIHint = "http-status-codes"
|
2023-03-07 12:45:58 +00:00
|
|
|
)]
|
|
|
|
|
public ICollection<HttpStatusCodeCase> ExpectedStatusCodes { get; set; } = new List<HttpStatusCodeCase>();
|
2023-03-07 13:54:21 +00:00
|
|
|
|
2023-03-07 12:45:58 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// The activity to execute when the HTTP status code does not match any of the expected status codes.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Port]
|
2023-03-11 21:14:39 +00:00
|
|
|
public IActivity? UnmatchedStatusCode { get; set; }
|
2023-03-07 12:45:58 +00:00
|
|
|
|
2023-09-10 19:31:57 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// The activity to execute when the HTTP request fails to connect.
|
|
|
|
|
/// </summary>
|
2025-09-17 16:31:03 +00:00
|
|
|
[Port]
|
2023-09-10 19:31:57 +00:00
|
|
|
public IActivity? FailedToConnect { get; set; }
|
2023-09-18 13:56:38 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The activity to execute when the HTTP request times out.
|
|
|
|
|
/// </summary>
|
2025-09-17 16:31:03 +00:00
|
|
|
[Port]
|
2023-09-18 13:56:38 +00:00
|
|
|
public IActivity? Timeout { get; set; }
|
2023-09-10 19:31:57 +00:00
|
|
|
|
2023-03-07 12:45:58 +00:00
|
|
|
/// <inheritdoc />
|
|
|
|
|
protected override async ValueTask HandleResponseAsync(ActivityExecutionContext context, HttpResponseMessage response)
|
|
|
|
|
{
|
|
|
|
|
var expectedStatusCodes = ExpectedStatusCodes;
|
|
|
|
|
var statusCode = (int)response.StatusCode;
|
|
|
|
|
var matchingCase = expectedStatusCodes.FirstOrDefault(x => x.StatusCode == statusCode);
|
2023-08-22 11:42:23 +00:00
|
|
|
var activity = matchingCase != null ? matchingCase.Activity : UnmatchedStatusCode;
|
2023-03-07 12:45:58 +00:00
|
|
|
|
|
|
|
|
await context.ScheduleActivityAsync(activity, OnChildActivityCompletedAsync);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-10 19:31:57 +00:00
|
|
|
/// <inheritdoc />
|
|
|
|
|
protected override async ValueTask HandleRequestExceptionAsync(ActivityExecutionContext context, HttpRequestException exception)
|
|
|
|
|
{
|
|
|
|
|
await context.ScheduleActivityAsync(FailedToConnect, OnChildActivityCompletedAsync);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-18 13:56:38 +00:00
|
|
|
/// <inheritdoc />
|
|
|
|
|
protected override async ValueTask HandleTaskCanceledExceptionAsync(ActivityExecutionContext context, TaskCanceledException exception)
|
|
|
|
|
{
|
|
|
|
|
await context.ScheduleActivityAsync(Timeout, OnChildActivityCompletedAsync);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-25 23:11:10 +00:00
|
|
|
private async ValueTask OnChildActivityCompletedAsync(ActivityCompletedContext context)
|
2023-03-07 12:45:58 +00:00
|
|
|
{
|
2023-08-25 23:11:10 +00:00
|
|
|
await context.TargetContext.CompleteActivityAsync();
|
2023-03-07 12:45:58 +00:00
|
|
|
}
|
2022-10-27 10:05:30 +00:00
|
|
|
}
|