Skip to content

Commit

Permalink
Merge pull request #80 from neuroglia-io/feat-resource-oriented
Browse files Browse the repository at this point in the history
Added the Resource Oriented infrastructure implementations
  • Loading branch information
cdavernas authored Mar 18, 2024
2 parents 1efe7a5 + e0890e2 commit 037032b
Show file tree
Hide file tree
Showing 178 changed files with 10,791 additions and 146 deletions.
39 changes: 37 additions & 2 deletions Neuroglia Framework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Mediation.Abstrac
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Integration", "src\Neuroglia.Integration\Neuroglia.Integration.csproj", "{B9DF1C37-F41F-4AC8-8BB0-19AD9EB978D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neuroglia.Measurements.Sdk.TypeScript", "src\Neuroglia.Measurements.Sdk.TypeScript\Neuroglia.Measurements.Sdk.TypeScript.csproj", "{4BA3F773-5C01-4064-9441-EED11C3264EC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Measurements.Sdk.TypeScript", "src\Neuroglia.Measurements.Sdk.TypeScript\Neuroglia.Measurements.Sdk.TypeScript.csproj", "{4BA3F773-5C01-4064-9441-EED11C3264EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neuroglia.Data.Schemas.Json", "src\Neuroglia.Data.Schemas.Json\Neuroglia.Data.Schemas.Json.csproj", "{A555095D-AA84-4D67-BF84-A0038EC783BD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Data.Schemas.Json", "src\Neuroglia.Data.Schemas.Json\Neuroglia.Data.Schemas.Json.csproj", "{A555095D-AA84-4D67-BF84-A0038EC783BD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Data.Infrastructure.ResourceOriented.Abstractions", "src\Neuroglia.Data.Infrastructure.ResourceOriented.Abstractions\Neuroglia.Data.Infrastructure.ResourceOriented.Abstractions.csproj", "{72220C70-CEDD-49E9-B682-03EFB1355833}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Security.Abstractions", "src\Neuroglia.Security.Abstractions\Neuroglia.Security.Abstractions.csproj", "{5F5F25CA-6368-4AC7-B71E-8BE4807DA115}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Security.AspNetCore", "src\Neuroglia.Security.AspNetCore\Neuroglia.Security.AspNetCore.csproj", "{661C5BA3-8EA4-45A1-A00F-64C7B5344003}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neuroglia.Data.Infrastructure.ResourceOriented", "src\Neuroglia.Data.Infrastructure.ResourceOriented\Neuroglia.Data.Infrastructure.ResourceOriented.csproj", "{602949C1-BC44-4E22-AA2E-C79EE5EDD083}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neuroglia.Data.Infrastructure.ResourceOriented.Redis", "src\Neuroglia.Data.Infrastructure.ResourceOriented.Redis\Neuroglia.Data.Infrastructure.ResourceOriented.Redis.csproj", "{25689B2F-D1F3-4611-8059-E43788C26407}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -284,6 +294,26 @@ Global
{A555095D-AA84-4D67-BF84-A0038EC783BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A555095D-AA84-4D67-BF84-A0038EC783BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A555095D-AA84-4D67-BF84-A0038EC783BD}.Release|Any CPU.Build.0 = Release|Any CPU
{72220C70-CEDD-49E9-B682-03EFB1355833}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72220C70-CEDD-49E9-B682-03EFB1355833}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72220C70-CEDD-49E9-B682-03EFB1355833}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72220C70-CEDD-49E9-B682-03EFB1355833}.Release|Any CPU.Build.0 = Release|Any CPU
{5F5F25CA-6368-4AC7-B71E-8BE4807DA115}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F5F25CA-6368-4AC7-B71E-8BE4807DA115}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F5F25CA-6368-4AC7-B71E-8BE4807DA115}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F5F25CA-6368-4AC7-B71E-8BE4807DA115}.Release|Any CPU.Build.0 = Release|Any CPU
{661C5BA3-8EA4-45A1-A00F-64C7B5344003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{661C5BA3-8EA4-45A1-A00F-64C7B5344003}.Debug|Any CPU.Build.0 = Debug|Any CPU
{661C5BA3-8EA4-45A1-A00F-64C7B5344003}.Release|Any CPU.ActiveCfg = Release|Any CPU
{661C5BA3-8EA4-45A1-A00F-64C7B5344003}.Release|Any CPU.Build.0 = Release|Any CPU
{602949C1-BC44-4E22-AA2E-C79EE5EDD083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{602949C1-BC44-4E22-AA2E-C79EE5EDD083}.Debug|Any CPU.Build.0 = Debug|Any CPU
{602949C1-BC44-4E22-AA2E-C79EE5EDD083}.Release|Any CPU.ActiveCfg = Release|Any CPU
{602949C1-BC44-4E22-AA2E-C79EE5EDD083}.Release|Any CPU.Build.0 = Release|Any CPU
{25689B2F-D1F3-4611-8059-E43788C26407}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25689B2F-D1F3-4611-8059-E43788C26407}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25689B2F-D1F3-4611-8059-E43788C26407}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25689B2F-D1F3-4611-8059-E43788C26407}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -333,6 +363,11 @@ Global
{B9DF1C37-F41F-4AC8-8BB0-19AD9EB978D7} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
{4BA3F773-5C01-4064-9441-EED11C3264EC} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
{A555095D-AA84-4D67-BF84-A0038EC783BD} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
{72220C70-CEDD-49E9-B682-03EFB1355833} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
{5F5F25CA-6368-4AC7-B71E-8BE4807DA115} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
{661C5BA3-8EA4-45A1-A00F-64C7B5344003} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
{602949C1-BC44-4E22-AA2E-C79EE5EDD083} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
{25689B2F-D1F3-4611-8059-E43788C26407} = {BDED6037-3D6E-4781-8C58-2EB7D0E53CEA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B390984D-3A9D-4F6D-A73B-E93CCEB586E4}
Expand Down
2 changes: 1 addition & 1 deletion src/Neuroglia..Eventing.CloudEvents/ICloudEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public interface ICloudEvent
{

/// <summary>
/// Gets/sets the version of the CloudEvents specification which the event uses. Defaults to <see cref="CloudEventSpecVersion.v1"/>
/// Gets/sets the version of the CloudEvents specification which the event uses. Defaults to <see cref="CloudEventSpecVersion.V1"/>
/// </summary>
string SpecVersion { get; }

Expand Down
8 changes: 3 additions & 5 deletions src/Neuroglia.Core/EnumMemberTypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@ namespace Neuroglia;
/// <summary>
/// Represents an <see cref="EnumConverter"/> used to convert enum using the values specified by <see cref="EnumMemberAttribute"/>s
/// </summary>
public class EnumMemberTypeConverter
: EnumConverter
/// <inheritdoc/>
public class EnumMemberTypeConverter([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] Type type)
: EnumConverter(type)
{

/// <inheritdoc/>
public EnumMemberTypeConverter([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] Type type) : base(type) { }

/// <inheritdoc/>
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
Expand Down
8 changes: 8 additions & 0 deletions src/Neuroglia.Core/Extensions/IEnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ public static object GetElementAt(this IEnumerable enumerable, int index)
throw new ArgumentOutOfRangeException(nameof(index));
}

/// <summary>
/// Joins the values of the <see cref="IEnumerable{T}"/> with the specified character
/// </summary>
/// <param name="values">The values to join</param>
/// <param name="separator">The separator char</param>
/// <returns>A new string that consists of the joined values, separated by the specified char</returns>
public static string Join(this IEnumerable<string> values, char separator) => string.Join(separator, values);

/// <summary>
/// Filters the elements of a sequence based on a specified type
/// </summary>
Expand Down
36 changes: 36 additions & 0 deletions src/Neuroglia.Core/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,42 @@ public static partial class StringExtensions

const string SubstitutionBlock = "§§";

/// <summary>
/// Determines whether or not the specified input only contains letters
/// </summary>
/// <param name="input">The input to check</param>
/// <returns>A boolean indicating whether or not the specified input only contains letters</returns>
public static bool IsAlphabetic(this string input) => input.All(char.IsLetter);

/// <summary>
/// Determines whether or not the specified input only contains digits
/// </summary>
/// <param name="input">The input to check</param>
/// <returns>A boolean indicating whether or not the specified input only contains digits</returns>
public static bool IsNumeric(this string input) => input.All(char.IsDigit);

/// <summary>
/// Determines whether or not the specified input only contains letters or digits
/// </summary>
/// <param name="input">The input to check</param>
/// <param name="exceptions">An array containing all exceptions allowed</param>
/// <returns>A boolean indicating whether or not the specified input only contains letters or digits</returns>
public static bool IsAlphanumeric(this string input, params char[] exceptions) => input.All(c => char.IsLetterOrDigit(c) || (exceptions != null && exceptions.Contains(c)));

/// <summary>
/// Determines whether or not the specified input is lowercased
/// </summary>
/// <param name="input">The input to check</param>
/// <returns>A boolean indicating whether or not the specified input is lowercased</returns>
public static bool IsLowercased(this string input) => input.Where(char.IsLetter).All(char.IsLower);

/// <summary>
/// Determines whether or not the specified input is uppercased
/// </summary>
/// <param name="input">The input to check</param>
/// <returns>A boolean indicating whether or not the specified input is uppercased</returns>
public static bool IsUppercased(this string input) => input.All(char.IsLower);

/// <summary>
/// Converts the string to its camel case representation
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Neuroglia.Core/IOperationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface IOperationResult
object? Data { get; }

/// <summary>
/// Gets a list containing the errors that have occured, if any, during the execution of the operation
/// Gets a list containing the errors that have occurred, if any, during the execution of the operation
/// </summary>
IReadOnlyCollection<Error>? Errors { get; }

Expand Down
4 changes: 2 additions & 2 deletions src/Neuroglia.Core/OperationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ protected OperationResult() { }
/// </summary>
/// <param name="status">A value that describes the status of the operation result</param>
/// <param name="data">The data, if any, returned by the operation in case of success</param>
/// <param name="errors">A list of the errors that have occured, if any, during the execution of the operation</param>
/// <param name="errors">A list of the errors that have occurred, if any, during the execution of the operation</param>
public OperationResult(int status, object? data = null, params Error[] errors)
{
this.Status = status;
Expand Down Expand Up @@ -80,7 +80,7 @@ protected OperationResult() { }
/// </summary>
/// <param name="status">A value that describes the status of the operation result</param>
/// <param name="data">The data, if any, returned by the operation in case of success</param>
/// <param name="errors">A list of the errors that have occured, if any, during the execution of the operation</param>
/// <param name="errors">A list of the errors that have occurred, if any, during the execution of the operation</param>
public OperationResult(int status, object? data = null, params Error[] errors) : base(status, data, errors) { }

/// <inheritdoc/>
Expand Down
98 changes: 98 additions & 0 deletions src/Neuroglia.Core/ProblemDetails.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright © 2021-Present Neuroglia SRL. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"),
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System.Runtime.Serialization;
using System.Text.Json.Serialization;

namespace Neuroglia;

/// <summary>
/// Represents an object used to describe a problem, as defined by <see href="https://www.rfc-editor.org/rfc/rfc7807">RFC 7807</see>
/// </summary>
[DataContract]
public record ProblemDetails
: IExtensible
{

/// <summary>
/// Initialize a new <see cref="ProblemDetails"/>
/// </summary>
public ProblemDetails() { }

/// <summary>
/// Initialize a new <see cref="ProblemDetails"/>
/// </summary>
/// <param name="type">An uri that reference the type of the described problem</param>
/// <param name="title">A short, human-readable summary of the problem type.It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization</param>
/// <param name="status">The status code produced by the described problem</param>
/// <param name="detail">A human-readable explanation specific to this occurrence of the problem</param>
/// <param name="instance">A <see cref="Uri"/> reference that identifies the specific occurrence of the problem.It may or may not yield further information if dereferenced</param>
/// <param name="errors">An optional collection containing error messages mapped per error code</param>
/// <param name="extensionData">A mapping containing problem details extension data, if any</param>
public ProblemDetails(Uri type, string title, int status, string? detail = null, Uri? instance = null, IEnumerable<KeyValuePair<string, string[]>>? errors = null, IDictionary<string, object>? extensionData = null)
{
this.Type = type ?? throw new ArgumentNullException(nameof(type));
this.Title = title ?? throw new ArgumentNullException(nameof(title));
this.Status = status;
this.Detail = detail;
this.Instance = instance;
this.Errors = errors?.WithValueSemantics();
this.ExtensionData = extensionData;
}

/// <summary>
/// Gets/sets an uri that reference the type of the described problem.
/// </summary>
[DataMember(Order = 1, Name = "type"), JsonPropertyName("type")]
public virtual Uri? Type { get; set; } = null!;

/// <summary>
/// Gets/sets a short, human-readable summary of the problem type.It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
/// </summary>
[DataMember(Order = 2, Name = "title"), JsonPropertyName("title")]
public virtual string? Title { get; set; } = null!;

/// <summary>
/// Gets/sets the status code produced by the described problem
/// </summary>
[DataMember(Order = 3, Name = "status"), JsonPropertyName("status"),]
public virtual int Status { get; set; }

/// <summary>
/// Gets/sets a human-readable explanation specific to this occurrence of the problem.
/// </summary>
[DataMember(Order = 4, Name = "detail"), JsonPropertyName("detail")]
public virtual string? Detail { get; set; }

/// <summary>
/// Gets/sets a <see cref="Uri"/> reference that identifies the specific occurrence of the problem.It may or may not yield further information if dereferenced.
/// </summary>
[DataMember(Order = 5, Name = "instance"), JsonPropertyName("instance")]
public virtual Uri? Instance { get; set; }

/// <summary>
/// Gets/sets an optional collection containing error messages mapped per error code
/// </summary>
[DataMember(Order = 6, Name = "errors"), JsonPropertyName("errors")]
public virtual EquatableList<KeyValuePair<string, string[]>>? Errors { get; set; }

/// <summary>
/// Gets/sets a mapping containing problem details extension data, if any
/// </summary>
[DataMember(Order = 7, Name = "extensionData"), JsonExtensionData]
public virtual IDictionary<string, object>? ExtensionData { get; set; }

/// <inheritdoc/>
public override string ToString() => this.Detail ?? Environment.NewLine + string.Join(Environment.NewLine, this.Errors?.Select(e => string.Join(Environment.NewLine, e.Value.Select(v => $"{e.Key}: {v}")))!);

}
32 changes: 32 additions & 0 deletions src/Neuroglia.Core/ProblemDetailsException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright © 2021-Present Neuroglia SRL. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"),
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Neuroglia;

/// <summary>
/// Represents an <see cref="Exception"/> described by <see cref="ProblemDetails"/>
/// </summary>
/// <remarks>
/// Initializes a new <see cref="ProblemDetailsException"/>
/// </remarks>
/// <param name="problem">An object that describes the problem that has occurred</param>
public class ProblemDetailsException(ProblemDetails problem)
: Exception($"[{problem.Status} - {problem.Title}] {problem.Detail}{(problem.Errors?.Count > 0 ? Environment.NewLine + string.Join(Environment.NewLine, problem.Errors.Select(e => $"{e.Key}: {string.Join(", ", e.Value)}")) : "")}")
{

/// <summary>
/// An object that describes the problem that has occurred
/// </summary>
public ProblemDetails Problem { get; } = problem;

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Neuroglia.Data.Expressions.JQ/JQExpressionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public virtual bool Supports(string language)
try { File.Delete(file); } catch { }
}

if (process.ExitCode != 0) throw new Exception($"An error occured while evaluting the specified expression: {error}");
if (process.ExitCode != 0) throw new Exception($"An error occurred while evaluting the specified expression: {error}");
if (string.IsNullOrWhiteSpace(output)) return null;
return this.Serializer.Deserialize(output, expectedType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public JavaScriptExpressionEvaluator(ILogger<JavaScriptExpressionEvaluator> logg
public virtual Task<object?> EvaluateAsync(string expression, object data, IDictionary<string, object>? args = null, Type? expectedType = null, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(expression)) throw new ArgumentNullException(nameof(expression));
if (data == null) throw new ArgumentNullException(nameof(data));
ArgumentNullException.ThrowIfNull(data);
if (expectedType == null) expectedType = typeof(object);
return Task.Run(() =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

<ItemGroup>
<PackageReference Include="Jint" Version="3.0.0-beta-2049" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="EventStore.Client.Grpc.PersistentSubscriptions" Version="23.1.0" />
<PackageReference Include="EventStore.Client.Grpc.Streams" Version="23.1.0" />
<PackageReference Include="EventStore.Client.Grpc.PersistentSubscriptions" Version="23.2.1" />
<PackageReference Include="EventStore.Client.Grpc.Streams" Version="23.2.1" />
<PackageReference Include="System.Reactive" Version="6.0.0" />
</ItemGroup>

Expand Down
Loading

0 comments on commit 037032b

Please sign in to comment.