First version of Service

This commit is contained in:
2025-06-22 19:34:07 -06:00
commit e99b2c5a5a
51 changed files with 2167 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
using Core.Inventory.External.Clients;
using Core.Inventory.External.GatewayConfigurations;
using Core.Inventory.External.Helpers;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Refit;
namespace Core.Inventory.External.ClientConfiguration
{
public static class RegisterClientConfiguration
{
public static IServiceCollection RegisterExternalLayer(this IServiceCollection services, IConfiguration configuration)
{
var gatewayConfiguration = new GatewayConfiguration();
var gatewaySettingsConfiguration = new GatewaySettingsConfigurations(configuration);
// Register GatewayConfiguration as a singleton
services.AddSingleton(gatewayConfiguration);
// Register IHttpContextAccessor
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// Register ITokenProvider
services.AddSingleton<ITokenProvider, HttpContextTokenProvider>();
// Register the custom AuthenticatedHttpClientHandler
services.AddTransient(provider =>
{
var tokenProvider = provider.GetRequiredService<ITokenProvider>();
var handler = new AuthenticatedHttpClientHandler(tokenProvider)
{
InnerHandler = new HttpClientHandler()
};
return handler;
});
var inventoryServiceApiUrl = GatewaySettingsConfigurations.GetInventoryServiceAPIEndpoint().Endpoint.Url;
// Register IInventoryServiceClient with the manually created HttpClient
services.AddScoped<IInventoryServiceClient>(provider =>
{
var handler = provider.GetRequiredService<AuthenticatedHttpClientHandler>();
var httpClient = new HttpClient(handler)
{
BaseAddress = new Uri(inventoryServiceApiUrl),
Timeout = TimeSpan.FromMinutes(1)
};
return RestService.For<IInventoryServiceClient>(httpClient);
});
services.AddScoped<IAuthenticationService, AuthenticationService>();
return services;
}
}
}

View File

@@ -0,0 +1,49 @@
using Core.Adapters.Lib;
using Core.Blueprint.Mongo;
using Core.Inventory.External.Clients.Requests;
using Microsoft.AspNetCore.Mvc;
using Refit;
namespace Core.Inventory.External.Clients
{
public interface IInventoryServiceClient
{
#region FurnitureBase
[Get("/api/v1/FurnitureBase")]
Task<IEnumerable<FurnitureBase>> GetAllFurnitureBaseAsync(CancellationToken cancellationToken = default);
[Get("/api/v1/FurnitureBase/{id}")]
Task<FurnitureBase> GetFurnitureBaseByIdAsync([FromRoute] string id, CancellationToken cancellationToken = default);
[Post("/api/v1/FurnitureBase")]
Task<FurnitureBase> CreateFurnitureBaseAsync([FromBody] FurnitureBaseRequest request, CancellationToken cancellationToken = default);
[Put("/api/v1/FurnitureBase/{id}")]
Task<FurnitureBase> UpdateFurnitureBaseAsync([FromBody] FurnitureBaseRequest request, [FromRoute] string id, CancellationToken cancellationToken = default);
[Patch("/api/v1/FurnitureBase/{id}/{newStatus}/ChangeStatus")]
Task<FurnitureBase> ChangeFurnitureBaseStatusAsync([FromRoute] string id, [FromRoute] StatusEnum newStatus, CancellationToken cancellationToken = default);
#endregion
#region FurnitureVariant
[Get("/api/v1/FurnitureVariant/{modelId}")]
Task<IEnumerable<FurnitureVariant>> GetAllVariantsByModelIdAsync([FromRoute] string modelId, CancellationToken cancellationToken = default);
[Get("/api/v1/FurnitureVariant/{id}/byId")]
Task<FurnitureVariant> GetFurnitureVariantByIdAsync([FromRoute] string id, CancellationToken cancellationToken = default);
[Post("/api/v1/FurnitureVariant")]
Task<FurnitureVariant> CreateFurnitureVariantAsync([FromBody] FurnitureVariantRequest request, CancellationToken cancellationToken = default);
[Put("/api/v1/FurnitureVariant/{id}")]
Task<FurnitureVariant> UpdateFurnitureVariantAsync([FromBody] FurnitureVariantRequest request, [FromRoute] string id, CancellationToken cancellationToken = default);
[Patch("/api/v1/FurnitureVariant/{id}/{newStatus}/ChangeStatus")]
Task<FurnitureVariant> ChangeFurnitureVariantStatusAsync([FromRoute] string id, [FromRoute] StatusEnum newStatus, CancellationToken cancellationToken = default);
#endregion
}
}

View File

@@ -0,0 +1,17 @@
using Core.Adapters.Lib;
namespace Core.Inventory.External.Clients.Requests
{
public class FurnitureBaseRequest
{
public string ModelName { get; set; } = null!;
public string Material { get; set; } = null!;
public string Condition { get; set; } = null!;
public string? BaseDescription { get; set; }
public string? Representation { get; set; }
public string? MaintenanceNotes { get; set; }
public Dimensions Dimensions { get; set; } = new();
public List<string>? VariantIds { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
namespace Core.Inventory.External.Clients.Requests
{
public class FurnitureVariantRequest
{
public string ModelId { get; set; } = null!;
public string Name { get; set; } = null!;
public string Color { get; set; } = null!;
public string? Line { get; set; }
public decimal Price { get; set; }
public string Currency { get; set; } = "USD";
public int Stock { get; set; }
public Guid CategoryId { get; set; }
public Guid ProviderId { get; set; }
public Dictionary<string, object> Attributes { get; set; } = [];
}
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Adapters.Lib" Version="1.0.3" />
<PackageReference Include="BuildingBlocks.Library" Version="1.0.0" />
<PackageReference Include="Refit" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,20 @@
using Core.Blueprint.External;
namespace Core.Inventory.External.GatewayConfigurations
{
public record GatewayConfiguration
{
public GatewayConfiguration()
{
InventoryService = new InventoryServiceAPI();
}
public InventoryServiceAPI InventoryService { get; set; }
}
public record InventoryServiceAPI
{
public string Channel { get; set; }
public BaseEndpoint Endpoint { get; set; }
}
}

View File

@@ -0,0 +1,52 @@
using Core.Blueprint.External;
using Microsoft.Extensions.Configuration;
namespace Core.Inventory.External.GatewayConfigurations
{
public class GatewaySettingsConfigurations
{
private static GatewayConfiguration GatewayConfigurations { get; set; } = new GatewayConfiguration();
private readonly IConfiguration _configuration;
public GatewaySettingsConfigurations(IConfiguration configuration)
{
_configuration = configuration;
this.SetInventoryServiceAPIEndpoint();
}
public static InventoryServiceAPI GetInventoryServiceAPIEndpoint()
{
return GatewayConfigurations.InventoryService;
}
private GatewayConfiguration SetInventoryServiceAPIEndpoint()
{
IConfigurationSection source;
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty;
if (environment == "Local")
source = _configuration.GetSection("LocalGateways");
else
source = _configuration.GetSection("Gateways");
var endpoint = source["InventoryDAL"] ?? string.Empty;
if (string.IsNullOrEmpty(endpoint))
throw new Exception("Inventory DAL endpoint is empty or null");
GatewayConfigurations.InventoryService = new InventoryServiceAPI()
{
Endpoint = new BaseEndpoint()
{
Uri = new Uri(endpoint),
Url = endpoint,
Token = string.Empty,
APIName = "Inventory Service"
}
};
return GatewayConfigurations;
}
}
}

View File

@@ -0,0 +1,26 @@
namespace Core.Inventory.External.Helpers
{
/// <summary>
/// Class to inject the token in all requests.
/// </summary>
public class AuthenticatedHttpClientHandler : DelegatingHandler
{
private readonly ITokenProvider _tokenProvider;
public AuthenticatedHttpClientHandler(ITokenProvider tokenProvider)
{
_tokenProvider = tokenProvider;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = _tokenProvider.GetToken();
if (!string.IsNullOrEmpty(token))
{
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
}
return await base.SendAsync(request, cancellationToken);
}
}
}

View File

@@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Http;
namespace Core.Inventory.External.Helpers
{
/// <summary>
/// Class to return the access token to controllers.
/// </summary>
public class HttpContextTokenProvider : ITokenProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextTokenProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// Get token from headers.
/// </summary>
public string GetToken()
{
return _httpContextAccessor.HttpContext?.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
}
}
}

View File

@@ -0,0 +1,13 @@
namespace Core.Inventory.External.Helpers
{
/// <summary>
/// Interface for token provider.
/// </summary>
public interface ITokenProvider
{
/// <summary>
/// Get token from headers.
/// </summary>
string GetToken();
}
}