-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #142 from Encamina/@mramos/factorial-improvements
v8.1.9 preview-02 release
- Loading branch information
Showing
13 changed files
with
307 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
...amina.Enmarcha.AspNet.OpenApi.Swashbuckle/SchemaFilters/AtLeastOneRequiredSchemaFilter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
using System.Reflection; | ||
|
||
using Encamina.Enmarcha.Core.DataAnnotations; | ||
|
||
using Microsoft.OpenApi.Models; | ||
|
||
using Swashbuckle.AspNetCore.SwaggerGen; | ||
|
||
namespace Encamina.Enmarcha.AspNet.OpenApi.Swashbuckle.SchemaFilters; | ||
|
||
/// <summary> | ||
/// This filter enforces that at least one of a specified set of properties must be required in an OpenAPI schema. | ||
/// It processes types decorated with the <see cref="AtLeastOneRequiredAttribute"/>. | ||
/// </summary> | ||
public sealed class AtLeastOneRequiredSchemaFilter : ISchemaFilter | ||
{ | ||
/// <summary> | ||
/// Applies the filter to modify the OpenAPI schema based on the <see cref="AtLeastOneRequiredAttribute"/>. | ||
/// It removes individual property requirements and replaces them with an 'anyOf' requirement | ||
/// for the specified properties, ensuring that at least one of them is present in the request. | ||
/// </summary> | ||
/// <param name="schema">The <see cref="OpenApiSchema"/> to modify.</param> | ||
/// <param name="context"> | ||
/// The <see cref="SchemaFilterContext"/> containing metadata about the context, including the type being processed. | ||
/// </param> | ||
public void Apply(OpenApiSchema schema, SchemaFilterContext context) | ||
{ | ||
var attribute = context.Type.GetCustomAttribute<AtLeastOneRequiredAttribute>(); | ||
if (attribute != null) | ||
{ | ||
// Add 'anyOf' to the schema with the specified properties | ||
schema.AnyOf = attribute.PropertyNames.Select(propertyName => new OpenApiSchema | ||
{ | ||
Required = new HashSet<string> { propertyName }, | ||
}).ToList(); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/Encamina.Enmarcha.Aspire/Encamina.Enmarcha.Aspire.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup> | ||
<PackageReadmeFile>README.md</PackageReadmeFile> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Aspire.Hosting" Version="8.2.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Include="README.md" Pack="true" PackagePath="\" /> | ||
</ItemGroup> | ||
|
||
</Project> |
31 changes: 31 additions & 0 deletions
31
src/Encamina.Enmarcha.Aspire/Extensions/ResourceBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using Aspire.Hosting; | ||
using Aspire.Hosting.ApplicationModel; | ||
|
||
using Encamina.Enmarcha.Aspire.Extensions; | ||
|
||
namespace Encamina.Enmarcha.Aspire.Extensions; | ||
|
||
/// <summary> | ||
/// Provides extension methods for configuring Aspire resources. | ||
/// </summary> | ||
public static class ResourceBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Adds an environment variable array to the resource. | ||
/// </summary> | ||
/// <typeparam name="T">The resource type.</typeparam> | ||
/// <param name="builder">The resource builder.</param> | ||
/// <param name="name">The name of the environment variable.</param> | ||
/// <param name="values">The array of values of the environment variable.</param> | ||
/// <returns>A resource configured with the specified environment variable.</returns> | ||
public static IResourceBuilder<T> WithEnvironment<T>(this IResourceBuilder<T> builder, string name, string[] values) where T : IResourceWithEnvironment | ||
{ | ||
return builder.WithEnvironment(context => | ||
{ | ||
for (var i = 0; i < values.Length; i++) | ||
{ | ||
context.EnvironmentVariables[$"{name}:{i}"] = values[i]; | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Enmarcha Aspire | ||
|
||
[![Nuget package](https://img.shields.io/nuget/v/Encamina.Enmarcha.Aspire)](https://www.nuget.org/packages/Encamina.Enmarcha.Aspire) | ||
|
||
Aspire Resource Builder Extensions is a set of tools designed to simplify the configuration of cloud-native resources with environment variables. This package is ideal for projects that need to manage distributed application resources in a cloud environment using environment-specific configurations. | ||
|
||
## Setup | ||
|
||
### Nuget package | ||
|
||
First, [install NuGet](http://docs.nuget.org/docs/start-here/installing-nuget). Then, install [Encamina.Enmarcha.Aspire](https://www.nuget.org/packages/Encamina.Enmarcha.Aspire) from the package manager console: | ||
|
||
PM> Install-Package Encamina.Enmarcha.Aspire | ||
|
||
### .NET CLI: | ||
|
||
[Install .NET CLI](https://learn.microsoft.com/en-us/dotnet/core/tools/). Next, install [Encamina.Enmarcha.Aspire](https://www.nuget.org/packages/Encamina.Enmarcha.Aspire) from the .NET CLI: | ||
|
||
dotnet add package Encamina.Enmarcha.Aspire | ||
|
||
## How to use | ||
|
||
### Resource Builder Extensions | ||
|
||
The `ResourceBuilderExtensions` class provides a set of extension methods to configure Aspire resources. | ||
|
||
```csharp | ||
var agentProjects = builder.AddProject<Projects.AgentProjects>(appIdProjects) | ||
.WithEnvironment(Constants.Settings.Options.PendingTaskStatuses, pendingTaskStatuses) | ||
``` |
84 changes: 84 additions & 0 deletions
84
src/Encamina.Enmarcha.Core/DataAnnotations/AtLeastOneRequiredAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Reflection; | ||
|
||
using Encamina.Enmarcha.Core.Extensions; | ||
|
||
using ValidationResultMessages = Encamina.Enmarcha.Core.DataAnnotations.Resources.ValudationResultMessages; | ||
|
||
namespace Encamina.Enmarcha.Core.DataAnnotations; | ||
|
||
/// <summary> | ||
/// Attribute that enforces validation on a class by requiring at least one of the specified properties to have a non-null or non-empty value. | ||
/// </summary> | ||
/// <remarks> | ||
/// This attribute is typically used on models to ensure that at least one of the specified properties is populated. | ||
/// If none of the specified properties have a value, the validation will fail. | ||
/// </remarks> | ||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] | ||
public sealed class AtLeastOneRequiredAttribute : ValidationAttribute | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AtLeastOneRequiredAttribute"/> class with the specified property names. | ||
/// </summary> | ||
/// <param name="propertyNames">An array of property names that must be validated.</param> | ||
public AtLeastOneRequiredAttribute(params string[] propertyNames) | ||
{ | ||
PropertyNames = propertyNames; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the array of property names that must be validated to ensure at least one has a value. | ||
/// </summary> | ||
public string[] PropertyNames { get; } | ||
|
||
/// <summary> | ||
/// Validates that at least one of the specified properties has a non-null or non-empty value. | ||
/// </summary> | ||
/// <param name="value">The object to validate, typically the class instance this attribute is applied to.</param> | ||
/// <param name="validationContext">Provides contextual information about the validation operation.</param> | ||
/// <returns> | ||
/// <see cref="ValidationResult.Success"/> if at least one property has a value; otherwise, a <see cref="ValidationResult"/> indicating the error. | ||
/// </returns> | ||
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) | ||
{ | ||
if (value is null) | ||
{ | ||
return ValidationResult.Success; | ||
} | ||
|
||
var type = value.GetType(); | ||
var atLeastOneHasValue = false; | ||
|
||
foreach (var propertyName in PropertyNames) | ||
{ | ||
var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); | ||
if (property == null) | ||
{ | ||
return new ValidationResult(ValidationResultMessages.ResourceManager.GetFormattedStringByCurrentCulture(nameof(ValidationResultMessages.PropertyNotFound), propertyName)); | ||
} | ||
|
||
var propertyValue = property.GetValue(value); | ||
if (propertyValue is string str) | ||
{ | ||
if (!string.IsNullOrWhiteSpace(str)) | ||
{ | ||
atLeastOneHasValue = true; | ||
break; | ||
} | ||
} | ||
else if (propertyValue != null) | ||
Check warning on line 69 in src/Encamina.Enmarcha.Core/DataAnnotations/AtLeastOneRequiredAttribute.cs GitHub Actions / CI
|
||
{ | ||
atLeastOneHasValue = true; | ||
break; | ||
} | ||
} | ||
|
||
if (!atLeastOneHasValue) | ||
{ | ||
var propertyNames = string.Join(", ", PropertyNames); | ||
return new ValidationResult(ValidationResultMessages.ResourceManager.GetFormattedStringByCurrentCulture(nameof(ValidationResultMessages.MissingRequiredProperty), propertyNames)); | ||
} | ||
|
||
return ValidationResult.Success; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 12 additions & 3 deletions
15
src/Encamina.Enmarcha.Core/DataAnnotations/Resources/ValudationResultMessages.Designer.cs
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters