Updated `InvokeRecActionCommand.cs` to use `using` statements for `HttpClient`, `HttpRequestMessage`, and `HttpResponseMessage` to prevent resource leaks.
Added a new `HttpExtensions.cs` file with a static `HttpExtensions` class as a placeholder for future HTTP-related extension methods. Included necessary `using` directives for potential LINQ, collections, and asynchronous programming.
Refactored the handling of "Rec Actions" by introducing the `InvokeRecActionCommandHandler` class and leveraging the MediatR library for command handling. Simplified the logic in `InvokeBatchRecActionsCommand.cs` by delegating HTTP request handling to the `sender.Send` method, which now uses `InvokeRecActionCommand`.
Updated `InvokeRecActionCommand` to implement the `IRequest` interface, enabling MediatR pipeline compatibility. Added `InvokeRecActionCommandExtensions` for converting `RecActionDto` to `InvokeRecActionCommand`, improving readability.
Centralized HTTP request logic in the new `InvokeRecActionCommandHandler`, which validates `RestType`, sends HTTP requests, and logs warnings for invalid actions. Removed unused `using` directives and added necessary ones for MediatR and logging.
This refactoring improves modularity, testability, and maintainability by separating concerns and streamlining the code structure.
Converted RecActionDto from class to record for immutability
and value-based equality. Added nullable properties
`ActionId` and `ProfileId` to RecActionDto.
Introduced InvokeRecActionCommand.cs, which includes:
- A new InvokeRecActionCommand record inheriting from RecActionDto.
- Constructors for initializing InvokeRecActionCommand.
- An extension method `ToInvokeCommand` for converting
RecActionDto to InvokeRecActionCommand.
Replaced `InvokeRecAction` with `InvokeBatchRecAction` in `ActionController` to transition from single-action to batch-action invocation.
Removed `InvokeRecActionCommand.cs`, which previously handled individual action invocations. Introduced `InvokeBatchRecActionsCommand.cs` to handle batch processing with similar concurrency control logic using a semaphore.
This redesign improves scalability and aligns with updated business requirements while maintaining compatibility with the existing application structure.
Refactored `InvokeRecActionCommand` and `ReadRecActionQuery`
to leverage C# `record` types for immutability and improved
data structure clarity. Introduced `ReadRecActionQueryBase`
as a shared base record to separate common properties and
logic. Updated `InvokeRecActionCommandHandler` to use the
new `ToReadQuery` method for compatibility. These changes
enhance code maintainability, reusability, and separation
of concerns while preserving existing functionality.
Introduced a new `RecAction` configuration section in `appsettings.json` with a `MaxConcurrentInvocations` property. Updated `Program.cs` to use the `Configuration` object to pass the `RecAction` settings to the `AddRecServices` method. Replaced the `MediatRLicense` value in `appsettings.json` with no functional changes.
Organized the `DependencyInjection` class into regions for better code structure: `Required Services`, `Configuration`, `LuckyPennySoftwareLicenseKey`, and `ConfigureRecActions`.
Added `_requiredServices` dictionary to track the configuration status of required services. Updated `LuckyPennySoftwareLicenseKey` to include a null check before marking it as configured.
Moved `_configActions` to the `Configuration` region and added `ApplyConfigurations` to process queued configuration actions.
Enhanced `ConfigureRecActions` to prevent duplicate configurations by throwing an `InvalidOperationException` if already configured.
These changes improve code readability, maintainability, and robustness.
Added `EnsureRequiredServices` to validate required services
in `ConfigurationOptions`, throwing an exception if any are
missing. Introduced `_requiredServices` dictionary to track
configuration status for `ConfigureRecActions` and
`LuckyPennySoftwareLicenseKey`. Updated property and methods
to mark services as configured. Integrated validation into
`AddRecServices` to enforce proper setup.
Updated `DependencyInjection.cs` to include support for
`ConfigurationOptions`, enabling queued configuration actions
and the ability to configure `RecActionOptions` via delegates
or `IConfiguration`. Added `LuckyPennySoftwareLicenseKey`
property to `ConfigurationOptions` and integrated it into
`AddAutoMapper` setup. Introduced `ApplyConfigurations`
method to process queued actions. Updated `using` directives
to include necessary namespaces.
A new `RecActionOptions` class was introduced in the
`ReC.Application.Common.Options` namespace. This class includes
a `MaxConcurrentInvocations` property with a default value of 5,
intended to configure the maximum number of concurrent invocations
allowed. This addition helps centralize and manage concurrency
settings in the application.
Updated `DtoMappingProfile` and `RecActionDto` to use the
`ReC.Application.Common.Dto` namespace instead of
`ReC.Application.Dto`. Adjusted `ReadRecActionQuery` to reflect
this namespace change. No functional changes were introduced.
Enhanced the `InvokeRecActionCommandHandler` class by adding
a `catch` block to handle exceptions during HTTP request and
response processing. Logged exception details, including
`ProfileId` and `ActionId`, using `logger?.LogError` for
better observability. Ensured the `finally` block releasing
the semaphore remains unaffected.
Enhanced the `InvokeRecActionCommandHandler` class by adding
logging functionality using `ILogger`. Updated the constructor
to accept an optional logger parameter. Introduced a check for
`RestType` being `null` and added a warning log to handle such
cases gracefully. This prevents processing invalid actions and
improves system robustness.
Introduced a `SemaphoreSlim` with a concurrency limit of 5 to
control the number of simultaneous HTTP requests. Updated the
HTTP request logic to use `WaitAsync` and `Release` for
managing access to the critical section. Wrapped the HTTP
request handling in a `try-finally` block to ensure proper
semaphore release, even in case of exceptions. This change
improves resource management and prevents overwhelming the
HTTP client or the target server.
Replaced sequential `foreach` loop with LINQ's `Select` to create a collection of tasks for sending HTTP requests asynchronously. Added `Task.WhenAll` to execute all requests concurrently, improving performance. Removed the old `foreach` implementation in favor of a functional programming approach.
Added a call to `services.AddHttpClient();` in the `DependencyInjection` class within `DependencyInjection.cs`. This change registers the `HttpClient` service in the dependency injection container, allowing the application to use managed `HttpClient` instances.
Updated `ReC.Application.csproj` to include `Microsoft.Extensions.Http` for improved HTTP client management. Refactored `InvokeRecActionCommandHandler` to use `IHttpClientFactory` for creating `HttpClient` instances, enhancing resource efficiency. Simplified HTTP method handling by replacing the switch statement with a dynamic `HttpMethod` and `HttpRequestMessage` approach. Removed redundant `using` directives and renamed `header` to `headers` for clarity. Removed `BadRequestException` for unsupported REST types, streamlining error handling.
In the `InvokeRecActionCommandHandler` class, added code to read the response content as a string and store it in a `body` variable. Also, converted response headers into a dictionary and stored them in a `header` variable. These changes facilitate further processing of the response content and headers.
Extended the switch expression in `InvokeRecActionCommand.cs` to handle additional HTTP methods: "PATCH", "HEAD", "OPTIONS", and "TRACE".
Implemented the appropriate asynchronous HTTP requests using `HttpClient`.
"PATCH" uses `http.PatchAsync`, while "HEAD", "OPTIONS", and "TRACE" use `http.SendAsync` with a new `HttpRequestMessage`.
A `BadRequestException` is thrown for unsupported methods.
Replaced the `switch` statement with a `switch` expression to handle HTTP methods (`GET`, `POST`, `PUT`, `DELETE`). This refactoring reduces boilerplate code and improves readability by directly assigning the HTTP request result to the `response` variable, eliminating the need for multiple `using` and `break` statements.
Implemented the handling of DELETE HTTP requests in the
InvokeRecActionCommandHandler class. Previously, the DELETE
case was unhandled, and now it uses http.DeleteAsync to
send a DELETE request to the specified action.EndpointUri,
supporting cancellation with the cancel token.
Implemented HTTP PUT request handling in the
InvokeRecActionCommandHandler class. Previously, the PUT case
only had a placeholder comment. Now, it uses
http.PutAsync to send a PUT request to the specified
action.EndpointUri, aligning it with the existing POST
request handling.
Previously, the handling of HTTP POST requests in the
InvokeRecActionCommandHandler class was not implemented.
This commit adds the necessary code to handle POST requests
by using the http.PostAsync method. The POST request is sent
to the specified action.EndpointUri with null content and a
cancellation token. This change ensures that POST operations
are now properly executed within the command handler.
Updated the HTTP request handling logic within the action loop to dynamically construct requests based on the `RestType` and `EndpointUri` of each action. Expanded the switch statement to handle GET, POST, PUT, and DELETE methods, allowing for specific logic to be implemented for each. Removed the hardcoded URL and response content retrieval, indicating potential refactoring of response handling. The default case continues to throw a `BadRequestException` for unsupported REST types.
Convert RestType to uppercase in the switch statement to
ensure case-insensitive matching of REST types. This change
handles variations like "get", "Get", and "GET" consistently.
Additionally, use the null-conditional operator to prevent
NullReferenceException when RestType is null.
Refactor `using` directives in `InvokeRecActionCommand.cs` to include `DigitalData.Core.Exceptions` and `System.Net.Http`.
Implement logic in `InvokeRecActionCommandHandler` to handle different REST actions using `HttpClient`. Introduce a `switch` statement to process "GET", "POST", "PUT", and "DELETE" actions, with a `BadRequestException` for unsupported types. Read HTTP response content asynchronously.
Updated `using` directives to include MediatR and related namespaces. Refactored `ActionController` to use constructor injection for `IMediator`. Modified the `Invoke` method to be asynchronous and replaced the placeholder `NotImplementedException` with a call to `mediator.InvokeRecAction(profileId)`. The method now returns an `Accepted` HTTP response to indicate successful request processing.
Introduce a new static class `InvokeRecActionCommandExtensions`
to extend the `ISender` interface with the `InvokeRecAction`
method. This method simplifies the invocation of
`InvokeRecActionCommand` by allowing callers to pass only the
`profileId`, internally creating and sending the command.
Replaced the `InvokeRecActionQuery` class with the `InvokeRecActionCommand` class to better align with CQRS semantics. The new class retains the same `ProfileId` property and implements the `IRequest` interface. Updated the namespace to remain consistent.
Introduced the `InvokeRecActionQuery` class in the `ReC.Application.RecActions.Commands` namespace to implement the Mediator pattern using the MediatR library.
- Added `using MediatR;` directive to include the library.
- Implemented `IRequest` interface in the new class.
- Added `ProfileId` property with `init` accessor for immutability.
- Organized the code under a new namespace for better structure.
Renamed `AddInfrastructureServices` to `AddRecInfrastructure`
in both generic and non-generic forms to standardize naming
and improve clarity. Updated `Program.cs` to use the new
method, adding database context configuration with a
connection string from the app's configuration.
Added a constraint to `AddRecInfrastructure<TRecDbContext>`
requiring `TRecDbContext` to inherit from `RecDbContext`.
Refactored the method to register entities from the assembly
containing `RecAction`. Removed the old
`AddInfrastructureServices` method entirely.
Added `AddRecServices` and `AddInfrastructureServices` to `Program.cs` with necessary configurations. Updated `ReC.API.csproj` to include project references to `ReC.Application` and `ReC.Infrastructure`, and fixed an encoding issue by adding a BOM. Modified `appsettings.json` to include `MediatRLicense` and adjusted `AllowedHosts` format. Ensured `TargetFramework` and other project properties remain unchanged.
Updated the `LuckyPennySoftwareLicenseKey` property in the
`ConfigurationOptions` class to allow null values by changing
it from a non-nullable string with a default value of an empty
string to a nullable string (`string?`). This change enables
explicit representation of the absence of a license key using
`null` instead of an empty string.
Introduced a new `DependencyInjection` class in the `ReC.Application` namespace to streamline service registration.
- Added `AddRecServices` extension method for `IServiceCollection` to configure AutoMapper and MediatR with assembly scanning.
- Included `ConfigurationOptions` class to allow configuration of a `LuckyPennySoftwareLicenseKey`.
- Added `using` directives for `Microsoft.Extensions.DependencyInjection` and `System.Reflection` to support dependency injection and assembly scanning.
Added `AutoMapper` and `MediatR` NuGet packages to the
`ReC.Application.csproj` file to include these libraries as
dependencies.
Created a `DtoMappingProfile` class in the `ReC.Application.Dto`
namespace to define a mapping configuration between the `RecAction`
entity and the `RecActionDto` data transfer object using `AutoMapper`.
Included necessary `using` directives for `AutoMapper` and
`ReC.Domain.Entities` in the `DtoMappingProfile.cs` file to enable
the mapping functionality.
These changes improve maintainability by automating object-to-object
mapping and prepare the project for potential use of the mediator
pattern with `MediatR`.
Added the `MediatR` NuGet package (v13.1.0) to enable the mediator pattern. Updated `ReC.Application.csproj` to include a project reference to `ReC.Domain`.
Introduced `RecActionDto` as a Data Transfer Object (DTO) for representing "RecAction" details, including properties for endpoints, authentication, and SQL connections.
Added `ReadRecActionQuery` to handle queries for retrieving `RecActionDto` objects, leveraging MediatR. This query filters results based on `ProfileId`.
Added `Microsoft.EntityFrameworkCore` and `ReC.Infrastructure` namespaces to `Program.cs` to enable EF Core functionality and infrastructure services. Configured the database context with a connection string from the app's configuration and added error handling for missing connection strings.
Updated `ReC.API.csproj` to include the `Microsoft.EntityFrameworkCore.SqlServer` NuGet package (v9.0.11) for SQL Server support. Added a project reference to `ReC.Infrastructure` to enable the API project to use the infrastructure layer.
Updated AddInfrastructureServices to support a generic
TRecDbContext type parameter, enabling the use of custom
DbContext types. Modified AddDbContext and AddDbRepository
to use the generic TRecDbContext type. Added an overload
of AddInfrastructureServices that defaults to RecDbContext
for backward compatibility. These changes enhance flexibility
and reusability while maintaining compatibility with existing
implementations.
Added `DigitalData.Core.Infrastructure` dependency and updated the `DependencyInjection` class to include `services.AddDbRepository` for dynamic repository registration from the `RecAction` assembly. Updated `ReC.Infrastructure.csproj` to include the new package reference. Improved dependency injection setup for better repository management.
Introduced a `DependencyInjection` class with an extension
method `AddInfrastructureServices` to register `RecDbContext`
using configurable `DbContextOptions`. Added a `ConfigurationOptions`
class to encapsulate `DbContext` configuration.
Validated that `DbContextOptionsAction` is provided before
registration. Updated `ReC.Infrastructure.csproj` to include
`Microsoft.Extensions.Configuration.Abstractions` for enhanced
configuration support. Added necessary `using` directives.
Replaced the `Action` class with a new `RecAction` class to represent the `VWREC_ACTION` database view. The `RecAction` class retains the same properties and annotations as the removed `Action` class, ensuring compatibility with the database schema.
Updated `RecDbContext` to use `RecAction`:
- Replaced `DbSet<Domain.Entities.Action>` with `DbSet<RecAction>`.
- Updated the `OnModelCreating` configuration to use `RecAction`.
This refactor improves clarity, aligns with naming conventions, and prepares the codebase for future changes.
Added the `Microsoft.EntityFrameworkCore` NuGet package to the
`ReC.Infrastructure` project to enable database functionality.
Introduced `RecDbContext` with `DbSet` properties for `EndpointParam`,
`Action`, and `OutRes` entities. Configured `Action` as a keyless
entity in `OnModelCreating`. Added a project reference to
`ReC.Domain` to use domain entities in the infrastructure layer.
The `Trigger` method in the `ActionController` class was renamed to `Invoke`. This change updates the HTTP POST endpoint that accepts a `profileId` as a route parameter. The method's functionality remains unchanged, as it still throws a `NotImplementedException`.
A new `OutRes` class was added to represent the `TBREC_OUT_RESULT` table in the `dbo` schema. The class includes properties for `Id`, `ActionId`, `ResultHeader`, `ResultBody`, `AddedWho`, `AddedWhen`, `ChangedWho`, and `ChangedWhen`, all mapped to corresponding database columns using data annotations. The `System.ComponentModel.DataAnnotations` and `System.ComponentModel.DataAnnotations.Schema` namespaces were imported to support this configuration.
Renamed the class `VwRecAction` to `Action` to simplify the name
and better align with naming conventions. The `[Table]` attribute
mapping to `VWREC_ACTION` in the `dbo` schema remains unchanged.
Class properties such as `ActionId` and `ProfileId` are unaffected
by this change.
Introduced the `EndpointParam` class to represent the `TBREC_CFG_ENDPOINT_PARAMS` table in the database.
- Added `using` directives for data annotations and table mapping.
- Defined properties to map to table columns, all nullable for flexibility.
- Annotated the class with `[Table]` and properties with `[Column]` attributes.
- Marked `Guid` as the primary key using the `[Key]` attribute.
- Documented the class with a summary explaining its purpose and design.
This change facilitates ORM integration and ensures schema flexibility.
Introduced the `VwRecAction` class to represent the `VWREC_ACTION`
database view. The class is annotated with `[Table]` and `[Column]`
attributes for schema mapping and includes nullable properties to
handle potential schema changes gracefully. Added `using` directives
for data annotations and schema mapping. Documented the class to
explain its purpose and design decisions, ensuring flexibility and
resilience against database schema evolution.