Add project files.

This commit is contained in:
Sergio Matias Urquin 2025-04-29 18:37:40 -06:00
parent ef5b7ed2ca
commit dacb004ae9
43 changed files with 1432 additions and 0 deletions

30
.dockerignore Normal file
View File

@ -0,0 +1,30 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**

View File

@ -0,0 +1,48 @@
using Lib.Architecture.BuildingBlocks.Presentation.Adapters;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Refit;
namespace Core.Blueprint.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class BaseController(ILogger<BaseController> logger) : ControllerBase
{
private readonly ILogger<BaseController> _logger = logger;
protected Guid TrackingId => (Guid)(HttpContext.Items["TrackingId"] ?? Guid.NewGuid());
protected async Task<IActionResult> Handle<T>(Func<Task<ApiResponse<T>>> apiCall) where T : class
{
var response = await apiCall().ConfigureAwait(false);
_logger.LogInformation($"{TrackingId} - {response.RequestMessage?.Method} {response.RequestMessage?.RequestUri} - Status: {response.StatusCode}");
return FromAPIResponse(response);
}
private IActionResult FromAPIResponse<T>(ApiResponse<T> response) where T : class
{
if (response.IsSuccessful)
return StatusCode((int)response.StatusCode, response.Content);
else
{
dynamic errorContent = string.Empty;
try
{
errorContent = JsonConvert.DeserializeObject<string>(response.Error?.Content ?? string.Empty) ?? string.Empty;
}
catch (Exception)
{
errorContent = JsonConvert.DeserializeObject<HttpError>(response.Error?.Content);
if (errorContent?.Error?.ErrorCode is null && errorContent?.Error?.Message is null && errorContent?.Error?.Target is null)
errorContent = JsonConvert.DeserializeObject<GenericErrorResponse>(response.Error?.Content);
}
return StatusCode((int)response.StatusCode, errorContent);
}
}
}
}

View File

@ -0,0 +1,130 @@
using Core.Blueprint.API.Controllers;
using Core.Blueprint.External.Clients.Blueprint;
using Core.Blueprint.External.Clients.Blueprint.Requests.BlobStorage;
using Lib.Architecture.BuildingBlocks;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace Core.Blob.API.Controllers
{
/// <summary>
/// Handles all requests for blob.
/// </summary>
[ApiVersion("1.0")]
//[Route("api/v{version:apiVersion}/[controller]")]
[Consumes("application/json")]
[Produces("application/json")]
[ApiController]
public class BlobStorageController(IBlueprintServiceClient blueprintServiceClient, ILogger<BlobStorageController> logger) : BaseController(logger)
{
/// <summary>
/// Uploads a new blob.
/// </summary>
[HttpPost("UploadBlob")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UploadBlobService(UploadBlobRequest newBlob, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(UploadBlobService)} - Request received - Payload: {JsonSerializer.Serialize(newBlob)}");
if (newBlob == null) return BadRequest("Invalid blob object");
if (string.IsNullOrEmpty(newBlob.BlobName)) return BadRequest("Invalid blob name");
if (newBlob.BlobContent is null) return BadRequest("Invalid blob content");
return await Handle(() => blueprintServiceClient.UploadBlobService(newBlob, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(UploadBlobService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(newBlob)}");
throw;
}
}
/// <summary>
/// Gets all blobs into the container.
/// </summary>
[HttpGet("GetBlobList")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetBlobListService([FromQuery] string? prefix, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(GetBlobListService)} - Request received - Payload: ");
return await Handle(() => blueprintServiceClient.GetBlobListAsync(prefix, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(GetBlobListService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload");
throw;
}
}
/// <summary>
/// Donwloads a blob by name.
/// </summary>
[HttpPost("DownloadBlob")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DownloadBlobService(DownloadBlobRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(DownloadBlobService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (string.IsNullOrEmpty(request.BlobName)) return BadRequest("Invalid blob name");
return await Handle(() => blueprintServiceClient.DownloadBlobAsync(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(DownloadBlobService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
/// <summary>
/// Deletes the blob by identifier.
/// </summary>
[HttpDelete("Delete")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteBlobService([FromBody] DeleteBlobRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(DeleteBlobService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (string.IsNullOrEmpty(request.BlobName)) return BadRequest("Invalid blob name");
return await Handle(() => blueprintServiceClient.DeleteBlobService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(DeleteBlobService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
}
}

View File

@ -0,0 +1,136 @@
using Core.Blueprint.API.Controllers;
using Core.Blueprint.External.Clients.Blueprint;
using Core.Blueprint.External.Clients.Blueprint.Requests.KeyVault;
using Lib.Architecture.BuildingBlocks;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace Core.Secret.API.Controllers
{
/// <summary>
/// Handles all requests for secret.
/// </summary>
[ApiVersion("1.0")]
//[Route("api/v{version:apiVersion}/[controller]")]
[Consumes("application/json")]
[Produces("application/json")]
[ApiController]
public class KeyVaultController(IBlueprintServiceClient blueprintServiceClient, ILogger<KeyVaultController> logger) : BaseController(logger)
{
/// <summary>
/// Creates a new secret.
/// </summary>
[HttpPost("Create")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> CreateSecretService(CreateSecretRequest newSecret, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(CreateSecretService)} - Request received - Payload: {JsonSerializer.Serialize(newSecret)}");
if (newSecret == null) return BadRequest("Invalid secret object");
if (string.IsNullOrEmpty(newSecret.Name)) return BadRequest("Invalid secret name");
if (string.IsNullOrEmpty(newSecret.Value)) return BadRequest("Invalid secret description");
return await Handle(() => blueprintServiceClient.CreateSecretService(newSecret, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(CreateSecretService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(newSecret)}");
throw;
}
}
/// <summary>
/// Gets the secret by identifier.
/// </summary>
[HttpPost("GetSecretByName")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetSecretByNameService(GetSecretRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(GetSecretByNameService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (string.IsNullOrEmpty(request.Name)) return BadRequest("Invalid secret name");
return await Handle(() => blueprintServiceClient.GetSecretByNameService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(GetSecretByNameService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
/// <summary>
/// Updates a full secret by identifier.
/// </summary>
[HttpPut("Update")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateSecretService(UpdateSecretRequest newSecret, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(UpdateSecretService)} - Request received - Payload: {JsonSerializer.Serialize(newSecret)}");
if (newSecret == null) return BadRequest("Invalid secret object");
if (string.IsNullOrEmpty(newSecret.Name)) return BadRequest("Invalid secret name");
if (string.IsNullOrEmpty(newSecret.Value)) return BadRequest("Invalid secret value");
return await Handle(() => blueprintServiceClient.UpdateSecretService(newSecret, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(UpdateSecretService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(newSecret)}");
throw;
}
}
/// <summary>
/// Deletes the secret by identifier.
/// </summary>
[HttpPost("Delete")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteSecretService(DeleteSecretRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(DeleteSecretService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (string.IsNullOrEmpty(request.Name)) return BadRequest("Invalid secret name");
return await Handle(() => blueprintServiceClient.DeleteSecretService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(DeleteSecretService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
}
}

View File

@ -0,0 +1,160 @@
using Core.Blueprint.External.Clients.Blueprint;
using Core.Blueprint.External.Clients.Blueprint.Requests.Mongo;
using Lib.Architecture.BuildingBlocks;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace Core.Blueprint.API.Controllers
{
/// <summary>
/// Handles all requests for blueprint.
/// </summary>
[ApiVersion("1.0")]
//[Route("api/v{version:apiVersion}/[controller]")]
[Consumes("application/json")]
[Produces("application/json")]
[ApiController]
public class MongoBlueprintController(IBlueprintServiceClient blueprintServiceClient, ILogger<MongoBlueprintController> logger) : BaseController(logger)
{
/// <summary>
/// Creates a new blueprint.
/// </summary>
[HttpPost("Create")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> CreateBlueprintService(CreateBlueprintRequest newBlueprint, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(CreateBlueprintService)} - Request received - Payload: {JsonSerializer.Serialize(newBlueprint)}");
if (newBlueprint == null) return BadRequest("Invalid blueprint object");
if (string.IsNullOrEmpty(newBlueprint.Name)) return BadRequest("Invalid blueprint name");
if (string.IsNullOrEmpty(newBlueprint.Description)) return BadRequest("Invalid blueprint description");
return await Handle(() => blueprintServiceClient.CreateBlueprintService(newBlueprint, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(CreateBlueprintService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(newBlueprint)}");
throw;
}
}
/// <summary>
/// Gets all blueprints.
/// </summary>
[HttpGet("GetAll")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllBlueprintsService(CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(GetAllBlueprintsService)} - Request received - Payload: ");
return await Handle(() => blueprintServiceClient.GetAllBlueprintsService(cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(GetAllBlueprintsService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload");
throw;
}
}
/// <summary>
/// Gets the blueprint by identifier.
/// </summary>
[HttpPost("GetById")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetBlueprintByIdService(GetBlueprintRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(GetBlueprintByIdService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (string.IsNullOrEmpty(request._Id)) return BadRequest("Invalid blueprint identifier");
return await Handle(() => blueprintServiceClient.GetBlueprintByIdService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(GetBlueprintByIdService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
/// <summary>
/// Updates a full blueprint by identifier.
/// </summary>
[HttpPut("Update")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateBlueprintService(UpdateBlueprintRequest newBlueprint, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(UpdateBlueprintService)} - Request received - Payload: {JsonSerializer.Serialize(newBlueprint)}");
if (newBlueprint == null) return BadRequest("Invalid blueprint object");
if (string.IsNullOrEmpty(newBlueprint.Name)) return BadRequest("Invalid blueprint name");
if (string.IsNullOrEmpty(newBlueprint.Description)) return BadRequest("Invalid blueprint description");
return await Handle(() => blueprintServiceClient.UpdateBlueprintService(newBlueprint, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(UpdateBlueprintService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(newBlueprint)}");
throw;
}
}
/// <summary>
/// Deletes the blueprint by identifier.
/// </summary>
[HttpPost("Delete")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteBlueprintService(DeleteBlueprintRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(DeleteBlueprintService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (string.IsNullOrEmpty(request._Id)) return BadRequest("Invalid blueprint identifier");
return await Handle(() => blueprintServiceClient.DeleteBlueprintService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(DeleteBlueprintService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
}
}

View File

@ -0,0 +1,165 @@
using Core.Blueprint.API.Controllers;
using Core.Blueprint.External.Clients.Blueprint;
using Core.Blueprint.External.Clients.Blueprint.Requests.SQL;
using Lib.Architecture.BuildingBlocks;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace Core.UserProject.API.Controllers
{
/// <summary>
/// Handles all requests for user project.
/// </summary>
[ApiVersion("1.0")]
//[Route("api/v{version:apiVersion}/[controller]")]
[Consumes("application/json")]
[Produces("application/json")]
[ApiController]
public class SQLUserProjectController(IBlueprintServiceClient blueprintServiceClient, ILogger<SQLUserProjectController> logger) : BaseController(logger)
{
/// <summary>
/// Creates a new user project.
/// </summary>
[HttpPost("Create")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> CreateUserProjectService(CreateUserProjectRequest newUserProject, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(CreateUserProjectService)} - Request received - Payload: {JsonSerializer.Serialize(newUserProject)}");
if (newUserProject == null) return BadRequest("Invalid user project object");
if (string.IsNullOrEmpty(newUserProject.ProjectCode)) return BadRequest("Invalid project code");
if (string.IsNullOrEmpty(newUserProject.ProjectDescription)) return BadRequest("Invalid project description");
if (string.IsNullOrEmpty(newUserProject.UserId)) return BadRequest("Invalid user identifier");
return await Handle(() => blueprintServiceClient.CreateUserProjectService(newUserProject, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(CreateUserProjectService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(newUserProject)}");
throw;
}
}
/// <summary>
/// Gets all user projects.
/// </summary>
[HttpGet("GetAll")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetAllUserProjectsService(CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(GetAllUserProjectsService)} - Request received - Payload: ");
return await Handle(() => blueprintServiceClient.GetAllUserProjectsService(cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(GetAllUserProjectsService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload");
throw;
}
}
/// <summary>
/// Gets the user project by identifier.
/// </summary>
[HttpPost("GetById")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetUserProjectByIdService(GetUserProjectRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(GetUserProjectByIdService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (request.Id <= 0) return BadRequest("Invalid user project identifier");
return await Handle(() => blueprintServiceClient.GetUserProjectByIdService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(GetUserProjectByIdService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
/// <summary>
/// Updates a full user project by identifier.
/// </summary>
[HttpPut("Update")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateUserProjectService(UpdateUserProjectRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(UpdateUserProjectService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (request == null) return BadRequest("Invalid user project object");
if (string.IsNullOrEmpty(request.ProjectCode)) return BadRequest("Invalid user project code");
if (string.IsNullOrEmpty(request.ProjectDescription)) return BadRequest("Invalid user project description");
if (string.IsNullOrEmpty(request.UserId)) return BadRequest("Invalid user identifier");
return await Handle(() => blueprintServiceClient.UpdateUserProjectService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(UpdateUserProjectService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
/// <summary>
/// Deletes the user project by identifier.
/// </summary>
[HttpPost("Delete")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status412PreconditionFailed)]
[ProducesResponseType(typeof(Notification), StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DeleteUserProjectService(DeleteUserProjectRequest request, CancellationToken cancellationToken)
{
try
{
logger.LogInformation($"{nameof(DeleteUserProjectService)} - Request received - Payload: {JsonSerializer.Serialize(request)}");
if (request.Id <= 0) return BadRequest("Invalid user project identifier");
return await Handle(() => blueprintServiceClient.DeleteUserProjectService(request, cancellationToken)).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogError($"{nameof(DeleteUserProjectService)} - An Error Occurred- {ex.Message} - {ex.InnerException} - {ex.StackTrace} - with payload {JsonSerializer.Serialize(request)}");
throw;
}
}
}
}

View File

@ -0,0 +1,6 @@
@Core.Blueprint.API_HostAddress = http://localhost:5239
GET {{Core.Blueprint.API_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>a9738f26-cc0a-4362-9b27-8e8bacd0b42d</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Core.Blueprint.Logging" Version="0.3.0-alpha0034" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.1.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="OpenTelemetry" Version="1.10.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.10.0" />
<PackageReference Include="Refit" Version="8.0.0" />
<PackageReference Include="Refit.HttpClientFactory" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core.Blueprint.External\Core.Blueprint.External.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,25 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["Core.Blueprint.API/Core.Blueprint.API.csproj", "Core.Blueprint.API/"]
RUN dotnet restore "./Core.Blueprint.API/Core.Blueprint.API.csproj"
COPY . .
WORKDIR "/src/Core.Blueprint.API"
RUN dotnet build "./Core.Blueprint.API.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Core.Blueprint.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Core.Blueprint.API.dll"]

View File

@ -0,0 +1,135 @@
using Azure.Identity;
using Core.Blueprint.External;
using Core.Blueprint.External.ClientConfiguration;
using Core.Blueprint.Logging.Configuration;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
using OpenTelemetry.Logs;
using OpenTelemetry.Resources;
using System.IO.Compression;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddAzureAppConfiguration(options =>
{
var endpoint = builder.Configuration.GetSection("Endpoints:AppConfigurationURI").Value;
if (string.IsNullOrEmpty(endpoint))
throw new ArgumentException("The app configuration is missing");
options.Connect(new Uri(endpoint), new DefaultAzureCredential())
.Select(KeyFilter.Any, "blueprint_api");
options.ConfigureKeyVault(keyVaultOptions =>
{
keyVaultOptions.SetCredential(new DefaultAzureCredential());
});
});
builder.Services.AddEndpointsApiExplorer();
builder.Configuration
.AddUserSecrets(Assembly.GetExecutingAssembly())
.AddEnvironmentVariables();
builder.Services.AddResponseCompression();
builder.Services.AddProblemDetails();
builder.Services.AddLogs(builder);
builder.Services.AddMemoryCache();
builder.Services.AddResponseCaching(configureOptions => { configureOptions.UseCaseSensitivePaths = true; });
builder.Logging.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("core.blueprint.bff.api")).AddConsoleExporter();
});
builder.Host.ConfigureServices((context, services) =>
{
builder.Services.AddHsts(options =>
{
options.Preload = true;
options.IncludeSubDomains = true;
options.MaxAge = TimeSpan.FromDays(60);
});
builder.Services.AddResponseCaching(configureOptions =>
{
configureOptions.UseCaseSensitivePaths = true;
configureOptions.MaximumBodySize = 2048;
});
builder.Services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = 308;
});
services.AddHttpLogging(http =>
{
http.CombineLogs = true;
});
services.AddAntiforgery();
services.AddCors(options =>
{
options.AddPolicy("AllowAll", policyBuilder =>
policyBuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
services.AddMvc().AddJsonOptions(options =>
{
options.JsonSerializerOptions.WriteIndented = true;
options.JsonSerializerOptions.MaxDepth = 20;
options.JsonSerializerOptions.NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals;
});
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.SmallestSize;
});
services.Configure<GzipCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.SmallestSize;
});
services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
});
services.AddResponseCaching();
services.AddControllers();
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
services.AddLogging();
services.AddProblemDetails();
services.AddHttpContextAccessor();
services.AddTransient<TrackingMechanismExtension>(); // Register the TrackingIdHandler
services.RegisterExternalLayer(builder.Configuration);
});
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
//*************************************************************************//
var app = builder.Build();
app.UseCors(options => options.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
app.UseSwagger();
app.UseSwaggerUI();
app.UseResponseCompression();
app.UseResponseCaching();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.UseHsts();
app.UseAntiforgery();
app.UseLogging(builder.Configuration);
app.Run();

View File

@ -0,0 +1,52 @@
{
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Local"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5239"
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Local"
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7056;http://localhost:5239"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Local"
}
},
"Container (Dockerfile)": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"environmentVariables": {
"ASPNETCORE_HTTPS_PORTS": "8081",
"ASPNETCORE_HTTP_PORTS": "8080"
},
"publishAllPorts": true,
"useSSL": true
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:54447",
"sslPort": 44347
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,11 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"LocalGateways": {
"BlueprintService": "https://localhost:7243/api"
}
}

View File

@ -0,0 +1,12 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Endpoints": {
"AppConfigurationURI": "https://sandbox-hci-usc-appcg.azconfig.io"
}
}

39
Core.Blueprint.BFF.sln Normal file
View File

@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34309.116
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Presentation", "Presentation", "{F3994F88-26E0-4123-8304-1FB0346E6A1F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core.Blueprint.BFF.API", "Core.Blueprint.API\Core.Blueprint.BFF.API.csproj", "{DD6855D6-B19A-4125-BC53-3BD856BF7D0B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Application", "Application", "{9DBA13A6-339F-4FD6-B53D-43F2D015C840}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Blueprint.External", "Core.Blueprint.External\Core.Blueprint.External.csproj", "{F18C641D-3064-4DCA-B843-CFE4D5F361F9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DD6855D6-B19A-4125-BC53-3BD856BF7D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD6855D6-B19A-4125-BC53-3BD856BF7D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD6855D6-B19A-4125-BC53-3BD856BF7D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD6855D6-B19A-4125-BC53-3BD856BF7D0B}.Release|Any CPU.Build.0 = Release|Any CPU
{F18C641D-3064-4DCA-B843-CFE4D5F361F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F18C641D-3064-4DCA-B843-CFE4D5F361F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F18C641D-3064-4DCA-B843-CFE4D5F361F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F18C641D-3064-4DCA-B843-CFE4D5F361F9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{DD6855D6-B19A-4125-BC53-3BD856BF7D0B} = {F3994F88-26E0-4123-8304-1FB0346E6A1F}
{F18C641D-3064-4DCA-B843-CFE4D5F361F9} = {9DBA13A6-339F-4FD6-B53D-43F2D015C840}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {771B556E-9EA3-46CD-BC3F-5DCF1098A8B7}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,65 @@
using Core.Blueprint.External.Clients.Blueprint;
using Core.Blueprint.External.GatewayConfigurations;
using Lib.Architecture.BuildingBlocks.Helpers.Token;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Refit;
namespace Core.Blueprint.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 trackingIdHandler = new TrackingMechanismExtension(provider.GetRequiredService<IHttpContextAccessor>());
var handler = new AuthenticatedHttpClientHandler(tokenProvider)
{
InnerHandler = new HttpClientHandler() // Setting the InnerHandler manually
};
// Attach the TrackingIdHandler as the outermost handler
trackingIdHandler.InnerHandler = handler;
return handler;
});
var blueprintServiceApiUrl = GatewaySettingsConfigurations.GetBlueprintServiceAPIEndpoint().Endpoint.Url;
// Register IDashBoardServiceClient with the manually created HttpClient
services.AddScoped(provider =>
{
var handler = provider.GetRequiredService<AuthenticatedHttpClientHandler>();
var handlerTrackingId = new TrackingMechanismExtension(provider.GetRequiredService<IHttpContextAccessor>()); // Using the TrackingIdHandler here
// Chain the handlers
handlerTrackingId.InnerHandler = handler; //chaining
var httpClient = new HttpClient(handlerTrackingId)
{
BaseAddress = new Uri(blueprintServiceApiUrl),
Timeout = TimeSpan.FromMinutes(1)
};
return RestService.For<IBlueprintServiceClient>(httpClient);
});
return services;
}
}
}

View File

@ -0,0 +1,17 @@
using Core.Blueprint.External.Clients.Blueprint.Requests;
namespace Core.Blueprint.External.Clients.Blueprint.Adapters
{
public class BlueprintAdapter
{
public string Name { get; set; } = null!;
public string? Description { get; set; }
public string _Id { get; set; } = null!;
public string Id { get; init; } = null!;
public DateTime CreatedAt { get; set; }
public string? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public string? UpdatedBy { get; set; }
public StatusEnum Status { get; set; }
}
}

View File

@ -0,0 +1,10 @@
using Core.Blueprint.KeyVault;
namespace Core.Blueprint.External.Clients.Blueprint.Adapters
{
public class KeyVaultAdapter
{
public KeyVaultResponse Item1 { get; set; }
public string Item2 { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using Core.Blueprint.External.Clients.Blueprint.Requests;
namespace Core.Blueprint.External.Clients.Blueprint.Adapters
{
public class UserProjectAdapter
{
public string ProjectCode { get; set; } = null!;
public string ProjectDescription { get; set; } = null!;
public string UserId { get; set; } = null!;
public int Id { get; set; }
public string Guid { get; set; } = null!;
public DateTime CreatedAt { get; set; }
public string? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public string? UpdatedBy { get; set; }
public StatusEnum Status { get; set; }
}
}

View File

@ -0,0 +1,70 @@
using Core.Blueprint.External.Clients.Blueprint.Adapters;
using Core.Blueprint.External.Clients.Blueprint.Requests.BlobStorage;
using Core.Blueprint.External.Clients.Blueprint.Requests.KeyVault;
using Core.Blueprint.External.Clients.Blueprint.Requests.Mongo;
using Core.Blueprint.External.Clients.Blueprint.Requests.SQL;
using Core.Blueprint.KeyVault;
using Core.Blueprint.Storage;
using Core.Blueprint.Storage.Adapters;
using Microsoft.AspNetCore.Mvc;
using Refit;
namespace Core.Blueprint.External.Clients.Blueprint
{
public interface IBlueprintServiceClient
{
[Post("/v1/MongoBlueprint/Create")]
Task<ApiResponse<BlueprintAdapter>> CreateBlueprintService([Body] CreateBlueprintRequest newBlueprint, CancellationToken cancellationToken = default);
[Get("/v1/MongoBlueprint/GetAll")]
Task<ApiResponse<IEnumerable<BlueprintAdapter>>> GetAllBlueprintsService(CancellationToken cancellationToken = default);
[Post("/v1/MongoBlueprint/GetById")]
Task<ApiResponse<BlueprintAdapter>> GetBlueprintByIdService([Body] GetBlueprintRequest request, CancellationToken cancellationToken = default);
[Put("/v1/MongoBlueprint/Update")]
Task<ApiResponse<BlueprintAdapter>> UpdateBlueprintService([Body] UpdateBlueprintRequest entity, CancellationToken cancellationToken = default);
[Delete("/v1/MongoBlueprint/Delete")]
Task<ApiResponse<BlueprintAdapter>> DeleteBlueprintService([Body] DeleteBlueprintRequest request, CancellationToken cancellationToken = default);
[Post("/v1/SQLUserProject/Create")]
Task<ApiResponse<UserProjectAdapter>> CreateUserProjectService([Body] CreateUserProjectRequest newUserProject, CancellationToken cancellationToken = default);
[Get("/v1/SQLUserProject/GetAll")]
Task<ApiResponse<IEnumerable<UserProjectAdapter>>> GetAllUserProjectsService(CancellationToken cancellationToken = default);
[Post("/v1/SQLUserProject/GetById")]
Task<ApiResponse<UserProjectAdapter>> GetUserProjectByIdService([Body] GetUserProjectRequest request, CancellationToken cancellationToken = default);
[Put("/v1/SQLUserProject/Update")]
Task<ApiResponse<UserProjectAdapter>> UpdateUserProjectService([Body] UpdateUserProjectRequest entity, CancellationToken cancellationToken = default);
[Delete("/v1/SQLUserProject/Delete")]
Task<ApiResponse<UserProjectAdapter>> DeleteUserProjectService([Body] DeleteUserProjectRequest request, CancellationToken cancellationToken = default);
[Post("/v1/KeyVault/CreateSecret")]
Task<ApiResponse<KeyVaultResponse>> CreateSecretService([Body] CreateSecretRequest newKeyVault, CancellationToken cancellationToken = default);
[Post("/v1/KeyVault/GetSecretByName")]
Task<ApiResponse<KeyVaultAdapter>> GetSecretByNameService([Body] GetSecretRequest request, CancellationToken cancellationToken = default);
[Put("/v1/KeyVault/UpdateSecret")]
Task<ApiResponse<KeyVaultAdapter>> UpdateSecretService([Body] UpdateSecretRequest entity, CancellationToken cancellationToken = default);
[Delete("/v1/KeyVault/DeleteSecret")]
Task<ApiResponse<KeyVaultAdapter>> DeleteSecretService([Body] DeleteSecretRequest request, CancellationToken cancellationToken = default);
[Post("/v1/BlobStorage/UploadBlob")]
Task<ApiResponse<BlobFileAdapter>> UploadBlobService([Body] UploadBlobRequest request, CancellationToken cancellationToken = default);
[Get("/v1/BlobStorage/GetBlobList")]
Task<ApiResponse<List<BlobFileAdapter>>> GetBlobListAsync([FromQuery] string? prefix, CancellationToken cancellationToken = default);
[Post("/v1/BlobStorage/DownloadBlob")]
Task<ApiResponse<BlobDownloadUriAdapter>> DownloadBlobAsync([Body] DownloadBlobRequest request, CancellationToken cancellationToken = default);
[Delete("/v1/BlobStorage/DeleteBlob")]
Task<ApiResponse<BlobFileAdapter>> DeleteBlobService([Body] DeleteBlobRequest request, CancellationToken cancellationToken = default);
}
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.BlobStorage
{
public class DeleteBlobRequest
{
public string BlobName { get; set; } = null!;
}
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.BlobStorage
{
public class DownloadBlobRequest
{
public string BlobName { get; set; } = null!;
}
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.BlobStorage
{
public class GetBlobListRequest
{
public string? Prefix { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.BlobStorage
{
public class UploadBlobRequest
{
public string BlobName { get; set; } = null!;
public byte[] BlobContent { get; set; } = null!;
}
}

View File

@ -0,0 +1,9 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.KeyVault
{
public class CreateSecretRequest
{
public string Name { get; set; } = null!;
public string Value { get; set; } = null!;
}
}

View File

@ -0,0 +1,6 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.KeyVault;
public class DeleteSecretRequest
{
public string Name { get; set; }
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.KeyVault
{
public class GetSecretRequest
{
public string Name { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.KeyVault
{
public class UpdateSecretRequest
{
public string Name { get; set; } = null!;
public string Value { get; set; } = null!;
}
}

View File

@ -0,0 +1,9 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.Mongo
{
public class CreateBlueprintRequest
{
public string Name { get; set; } = null!;
public string? Description { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.Mongo
{
public class DeleteBlueprintRequest
{
public string _Id { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.Mongo
{
public class GetAllBlueprintsRequest
{
}
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.Mongo
{
public class GetBlueprintRequest
{
public string _Id { get; set; }
}
}

View File

@ -0,0 +1,15 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.Mongo
{
public class UpdateBlueprintRequest
{
public string Name { get; set; } = null!;
public string? Description { get; set; }
public string _Id { get; set; } = null!;
public string Id { get; init; } = null!;
public DateTime CreatedAt { get; set; }
public string? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public string? UpdatedBy { get; set; }
public StatusEnum Status { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.SQL
{
public class CreateUserProjectRequest
{
public string ProjectCode { get; set; } = null!;
public string ProjectDescription { get; set; } = null!;
public string UserId { get; set; } = null!;
}
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.SQL
{
public class DeleteUserProjectRequest
{
public int Id { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.SQL
{
public class GetAllUserProjectsRequest
{
}
}

View File

@ -0,0 +1,7 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.SQL
{
public class GetUserProjectRequest
{
public int Id { get; set; }
}
}

View File

@ -0,0 +1,16 @@
namespace Core.Blueprint.External.Clients.Blueprint.Requests.SQL
{
public class UpdateUserProjectRequest
{
public string ProjectCode { get; set; } = null!;
public string ProjectDescription { get; set; } = null!;
public string UserId { get; set; } = null!;
public int Id { get; set; }
public string Guid { get; set; } = null!;
public DateTime CreatedAt { get; set; }
public string? CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public string? UpdatedBy { get; set; }
public StatusEnum Status { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace Core.Blueprint.External.Clients.Blueprint.Requests
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum StatusEnum
{
Active = 0,
Inactive = 1,
Deleted = 2
}
}

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Core.Blueprint.KeyVault" Version="0.3.0-alpha0037" />
<PackageReference Include="Core.Blueprint.Storage" Version="0.3.0-alpha0049" />
<PackageReference Include="Lib.Architecture.BuildingBlocks" Version="0.9.0-alpha0008" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
<PackageReference Include="Refit" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,17 @@
namespace Core.Blueprint.External.GatewayConfigurations
{
public record GatewayConfiguration
{
public GatewayConfiguration()
{
BlueprintService = new BlueprintServiceAPI();
}
public BlueprintServiceAPI BlueprintService { get; set; }
}
public record BlueprintServiceAPI
{
public string Channel { get; set; }
public BaseEndpoint Endpoint { get; set; }
}
}

View File

@ -0,0 +1,46 @@
using Microsoft.Extensions.Configuration;
namespace Core.Blueprint.External.GatewayConfigurations
{
public class GatewaySettingsConfigurations
{
private static GatewayConfiguration GatewayConfigurations { get; set; } = new GatewayConfiguration();
private readonly IConfiguration _configuration;
public GatewaySettingsConfigurations(IConfiguration configuration)
{
_configuration = configuration;
SetBlueprintServiceAPIEndpoint();
}
public static BlueprintServiceAPI GetBlueprintServiceAPIEndpoint()
{
return GatewayConfigurations.BlueprintService;
}
private GatewayConfiguration SetBlueprintServiceAPIEndpoint()
{
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["BlueprintService"] ?? string.Empty;
GatewayConfigurations.BlueprintService = new BlueprintServiceAPI()
{
Endpoint = new BaseEndpoint()
{
Uri = new Uri(endpoint),
Url = endpoint,
Token = string.Empty,
APIName = "Blueprint Service"
}
};
return GatewayConfigurations;
}
}
}

View File

@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Http;
namespace Core.Blueprint.External
{
public sealed class TrackingMechanismExtension(IHttpContextAccessor httpContextAccessor) : DelegatingHandler
{
private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (_httpContextAccessor.HttpContext != null)
{
request.Headers.Add("TrackingId", Guid.NewGuid().ToString());
}
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}
}