[성현모] UniqueKeyApi REST 완료

This commit is contained in:
SHM
2025-08-05 08:46:05 +09:00
parent d138088df9
commit afa4940880
15 changed files with 647 additions and 13 deletions

View File

@ -0,0 +1,30 @@
{
"Server": {
"Address": "https://*",
"Port": 9000,
"IIS": false
},
"Socket": {
"Address": "*",
"Port": 9010,
"IIS": false
},
"DataBase": [
{
"IP": "127.0.0.1",
"Port": 1433,
"DBName": "UniqueKeyDB",
"DBID": 1,
"UserID": "SystemX",
"Password": "X"
},
{
"IP": "127.0.0.1",
"Port": 1433,
"DBName": "UniqueKeyDB_DEV",
"DBID": 2,
"UserID": "SystemX",
"Password": "X"
}
]
}

View File

@ -92,18 +92,6 @@ if (configService?.OpenConfig($@"{configDir}/{configFileName}") == true)
var dbProvider = scoped.ServiceProvider.GetRequiredService<DbContextProvider>(); var dbProvider = scoped.ServiceProvider.GetRequiredService<DbContextProvider>();
dbProvider?.SetDBList(apiConfig?.DataBase); dbProvider?.SetDBList(apiConfig?.DataBase);
} }
//dbcontext set
//app.Use(async (context, next) =>
//{
// var dbProvider = context.RequestServices.GetService<DbContextProvider>();
// // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// dbProvider?.SetDBList(apiConfig?.DataBase);
// await next.Invoke();
//});
//var dbProviderService = app.Services.GetService<DbContextProvider>();
//dbProviderService?.SetDBList(apiConfig?.DataBase);
} }
} }
else else

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WebApi.Library.Enums
{
public enum WebApiResult
{
Success = 1,
Failed = 2,
}
}

View File

@ -0,0 +1,85 @@
using Azure;
using Azure.Core;
using Microsoft.AspNetCore.Mvc;
using SystemX.Core.Controller;
using WebApi.Library.Config;
using WebApi.Project.UniqueKeyApi.Models;
using WebApi.Project.UniqueKeyApi.Services;
namespace WebApi.Project.UniqueKeyApi.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
public class UniqueKeyController : CommonController<UniqueKeyApiConfig>
{
private readonly UniqueKeyService _uniqueKeyService;
public UniqueKeyController(IServiceProvider serviceProvider, IHttpContextAccessor httpContextAccessor, UniqueKeyService uniqueKeyService)
: base(serviceProvider, httpContextAccessor)
{
_uniqueKeyService = uniqueKeyService;
}
[HttpGet("health")]
public async Task<IResult> Health()
{
LogXnet.WriteLine($"[{GetRequestMethod()}:{GetMethodName()}] [Client IP:{GetClientIP()}] [RequestUrl:{GetRequestUrl()}]{Environment.NewLine}", LogXLabel.CONTROLLER);
await Task.CompletedTask;
return Results.Ok("Healthy");
}
[HttpPost]
public async Task<IResult> InsertUniqueKey(Request_InsertUniqueKey request)
{
Guid guid = Guid.NewGuid();
LogXnet.WriteLine($"[Request][{GetRequestMethod()}:{GetMethodName()}][Client IP:{GetClientIP()}][RequestUrl:{GetRequestUrl()}]::({guid}){Environment.NewLine} {request.ToJson()}", LogXLabel.CONTROLLER);
Response_InsertUniqueKy response = await _uniqueKeyService.Request_InsertUniqueKey(request);
LogXnet.WriteLine($"[Response]::({guid}){Environment.NewLine} {response.ToJson()}", LogXLabel.CONTROLLER);
return Results.Ok(response);
}
[HttpPost]
public async Task<IResult> SelectUniqueKey([FromBody]Request_SelectUniqueKey request)
{
Guid guid = Guid.NewGuid();
LogXnet.WriteLine($"[Request][{GetRequestMethod()}:{GetMethodName()}][Client IP:{GetClientIP()}][RequestUrl:{GetRequestUrl()}]::({guid}){Environment.NewLine} {request.ToJson()}", LogXLabel.CONTROLLER);
Response_SelectUniqueKy response = await _uniqueKeyService.Request_SelectUniqueKey(request);
LogXnet.WriteLine($"[Response]::({guid}){Environment.NewLine} {response.ToJson()}", LogXLabel.CONTROLLER);
return Results.Ok(response);
}
[HttpGet]
public async Task<IResult> SelectUniqueKeyGet([FromQuery] string key)
{
Guid guid = Guid.NewGuid();
LogXnet.WriteLine($"[Request][{GetRequestMethod()}:{GetMethodName()}][Client IP:{GetClientIP()}][RequestUrl:{GetRequestUrl()}]::({guid}){Environment.NewLine} key:{key}", LogXLabel.CONTROLLER);
Response_SelectUniqueKy response = await _uniqueKeyService.Request_SelectUniqueKey(new Request_SelectUniqueKey { Identity = key });
LogXnet.WriteLine($"[Response]::({guid}){Environment.NewLine} {response.ToJson()}", LogXLabel.CONTROLLER);
return Results.Ok(response);
}
[HttpPost]
public async Task<IResult> UpdateUniqueKey(Request_UpdateUniqueKey request)
{
Guid guid = Guid.NewGuid();
LogXnet.WriteLine($"[Request][{GetRequestMethod()}:{GetMethodName()}][Client IP:{GetClientIP()}][RequestUrl:{GetRequestUrl()}]::({guid}){Environment.NewLine} {request.ToJson()}", LogXLabel.CONTROLLER);
Response_UpdateUniqueKy response = await _uniqueKeyService.Request_UpdateUniqueKey(request);
LogXnet.WriteLine($"[Response]::({guid}){Environment.NewLine} {response.ToJson()}", LogXLabel.CONTROLLER);
return Results.Ok(response);
}
}
}

View File

@ -0,0 +1,55 @@
using WebApi.Library.Enums;
namespace WebApi.Project.UniqueKeyApi.Models
{
#region Unique Key
//Insert
public class Request_InsertUniqueKey
{
public string Identity { get; set; } = string.Empty;
public string? Data1 { get; set; } = string.Empty;
public string? Data2 { get; set; } = string.Empty;
public string? Data3 { get; set; } = string.Empty;
public string? Data4 { get; set; } = string.Empty;
public string? Data5 { get; set; } = string.Empty;
}
public class Response_InsertUniqueKy
{
public string? Identity { get; set; } = string.Empty;
public string? Result { get; set; } = WebApiResult.Success.ToString();
}
//Select
public class Request_SelectUniqueKey
{
public string Identity { get; set; } = string.Empty;
}
public class Response_SelectUniqueKy
{
public string? Identity { get; set; } = string.Empty;
public string? Data1 { get; set; } = string.Empty;
public string? Data2 { get; set; } = string.Empty;
public string? Data3 { get; set; } = string.Empty;
public string? Data4 { get; set; } = string.Empty;
public string? Data5 { get; set; } = string.Empty;
}
//Update
public class Request_UpdateUniqueKey
{
public string Identity { get; set; } = string.Empty;
public string? Data1 { get; set; } = string.Empty;
public string? Data2 { get; set; } = string.Empty;
public string? Data3 { get; set; } = string.Empty;
public string? Data4 { get; set; } = string.Empty;
public string? Data5 { get; set; } = string.Empty;
}
public class Response_UpdateUniqueKy
{
public string? Identity { get; set; } = string.Empty;
public string? Result { get; set; } = WebApiResult.Success.ToString();
}
#endregion
}

View File

@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
using SystemX.Core.Config.Model;
using WebApi.Library.Config;
namespace WebApi.Project.UniqueKeyApi.Models
{
public class UniqueKeyApiConfig : WebApiConfig
{
[JsonPropertyName("Socket")]
public Server Socket { get; set; }
}
}

View File

@ -0,0 +1,109 @@
using SystemX.Core.Services;
using WebApi.Library.Config;
using WebApi.Project.UniqueKeyApi.Models;
using WebApi.Project.UniqueKeyApi.Services;
using WebApi.Project.UniqueKeyApi.TaskManager;
string configDir = @"../../Config";
string configFileName = "WebApi.Project.UniqueKeyApi.Config.json";
//raed log4net configs
if (LogXnet.ReadConfig(@$"{configDir}/LogXnetConfig.json") == true)
{
LogXnet.WriteLine("LogXnet Init Success");
}
else
{
Console.WriteLine("LogXnet Init Failed");
return;
}
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
//singleton
builder.Services.AddSingleton<ConfigService<UniqueKeyApiConfig>>();
//scoped
builder.Services.AddSingleton<UniqueKeyService>();
//db
builder.Services.AddSingleton<DbContextProvider>(); // Generic <20><><EFBFBD><EFBFBD>
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpContextAccessor();
//config preload, auth set
ConfigService<UniqueKeyApiConfig> preloadConfig = new ConfigService<UniqueKeyApiConfig>();
if (preloadConfig.OpenConfig($@"{configDir}/{configFileName}") == true)
{
var config = preloadConfig.GetConfig();
}
else
{
LogXnet.WriteLine("Config Preload Load Error.", LogXLabel.Error);
return;
}
var app = builder.Build();
//read api config and set
string serverUrl = string.Empty;
var configService = app.Services.GetService<ConfigService<UniqueKeyApiConfig>>();
bool isIIS = false;
int socketPort = 0;
if (configService?.OpenConfig($@"{configDir}/{configFileName}") == true)
{
LogXnet.WriteLine("WebApi Config Success.");
var apiConfig = ConfigService<UniqueKeyApiConfig>.Config;
if (apiConfig != null)
{
serverUrl = $"{apiConfig?.Server?.Address}:{apiConfig?.Server?.Port}";
isIIS = apiConfig!.Server.IIS;
socketPort = apiConfig.Socket.Port;
using (var scoped = app.Services.CreateScope())
{
var dbProvider = scoped.ServiceProvider.GetRequiredService<DbContextProvider>();
dbProvider?.SetDBList(apiConfig?.DataBase);
}
}
}
else
{
LogXnet.WriteLine("WebApi Config Error.");
return;
}
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
LogXnet.WriteLine($"IsDevelopment:{app.Environment.IsDevelopment()}");
LogXnet.WriteLine($"Swagger Url: {serverUrl}/swagger");
app.UseSwagger();
app.UseSwaggerUI();
}
//TaskSocket taskSocket = new TaskSocket();
//taskSocket?.Run(socketPort);
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
if (isIIS == true)
{
app.Run();
}
else
{
LogXnet.WriteLine($"Operation Url: {serverUrl}");
app.Run($"{serverUrl}");
}

View File

@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:13996",
"sslPort": 44374
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5161",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7291;http://localhost:5161",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,216 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Identity.Client.Extensions.Msal;
using System.Data;
using SystemX.Core.DB;
using SystemX.Core.Services;
using WebApi.Library.Config;
using WebApi.Library.Enums;
using WebApi.Project.UniqueKeyApi.Models;
namespace WebApi.Project.UniqueKeyApi.Services
{
public class UniqueKeyService
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly ConfigService<UniqueKeyApiConfig>? _configService;
public UniqueKeyService(IServiceProvider serviceProvider, IServiceScopeFactory scopeFactory, ConfigService<UniqueKeyApiConfig> configSerice)
{
_scopeFactory = scopeFactory;
_configService = configSerice;
}
public async Task<Response_InsertUniqueKy> Request_InsertUniqueKey(Request_InsertUniqueKey request, string guid = "")
{
Response_InsertUniqueKy response = new Response_InsertUniqueKy();
if (request != null)
{
response.Identity = request.Identity;
bool transactionResult = true;
using (var scope = _scopeFactory.CreateScope())
{
var provider = scope.ServiceProvider.GetRequiredService<DbContextProvider>();
using (var context = GetUniqueKeyDBContext(provider, 1))
{
if(context is not null)
{
var data = await context.tUniqueKeyStorages.AsNoTracking().Where(x => x.cIdentity== request.Identity).ToListAsync();
if (data?.Count() > 0)
{
LogXnet.WriteLine($"Exist Unique Key::{guid}", LogXLabel.Error);
response.Result = "Exist Unique Key";
}
else
{
var storage = new tUniqueKeyStorage
{
cIdentity = request.Identity,
cData1 = request.Data1,
cData2 = request.Data2,
cData3 = request.Data3,
cData4 = request.Data4,
cData5 = request.Data5,
cDateTime = DateTime.Now
};
using (var transaction = await context.CreateTransactionAsync())
{
await context.AddAsync(storage);
transactionResult = await context.CloseTransactionAsync(transaction);
}
//db error
if (transactionResult == false)
{
response.Result = WebApiResult.Failed.ToString();
LogXnet.WriteLine($"Transaction Error::{guid}", LogXLabel.Error);
}
else
{
LogXnet.WriteLine($"Transaction Success", LogXLabel.DB);
}
}
}
}
}
}
return response;
}
public async Task<Response_SelectUniqueKy> Request_SelectUniqueKey(Request_SelectUniqueKey request, string guid = "")
{
Response_SelectUniqueKy response = new Response_SelectUniqueKy();
if (request != null)
{
response.Identity = request.Identity;
using (var scope = _scopeFactory.CreateScope())
{
var provider = scope.ServiceProvider.GetRequiredService<DbContextProvider>();
using(var context = GetUniqueKeyDBContext(provider, 1))
{
if (context is not null)
{
try
{
using (var transaction = await context.CreateTransactionAsync(IsolationLevel.ReadUncommitted))
{
var data = await context.tUniqueKeyStorages.AsNoTracking().FirstOrDefaultAsync(x => x.cIdentity == request.Identity);
await context.CloseTransactionAsync(transaction);
if (data != null)
{
response.Data1 = data.cData1;
response.Data2 = data.cData2;
response.Data3 = data.cData3;
response.Data4 = data.cData4;
response.Data5 = data.cData5;
}
}
}
catch (Exception e)
{
LogXnet.WriteLine($"Select Unique Key Transaction Error::{guid}", LogXLabel.Error);
LogXnet.WriteLine(e);
}
}
}
}
}
return response;
}
public async Task<List<tUniqueKeyStorage>> Request_SelectUniqueKeyAll(string guid = "")
{
List<tUniqueKeyStorage> result = new List<tUniqueKeyStorage>();
using (var scope = _scopeFactory.CreateScope())
{
var provider = scope.ServiceProvider.GetRequiredService<DbContextProvider>();
using(var context = GetUniqueKeyDBContext(provider, 1))
{
if (context is not null)
{
try
{
using (var transaction = await context.CreateTransactionAsync(IsolationLevel.ReadUncommitted))
{
result = await context.tUniqueKeyStorages.AsNoTracking().ToListAsync();
await context.CloseTransactionAsync(transaction);
}
}
catch (Exception e)
{
LogXnet.WriteLine($"Select Unique Key Transaction Error::{guid}", LogXLabel.Error);
LogXnet.WriteLine(e);
}
}
}
}
return result;
}
public async Task<Response_UpdateUniqueKy> Request_UpdateUniqueKey(Request_UpdateUniqueKey request, string guid = "")
{
Response_UpdateUniqueKy response = new Response_UpdateUniqueKy();
if (request != null)
{
response.Identity = request.Identity;
bool transactionResult = true;
using (var scope = _scopeFactory.CreateScope())
{
var provider = scope.ServiceProvider.GetRequiredService<DbContextProvider>();
using(var context = GetUniqueKeyDBContext(provider, 1))
{
if (context != null)
{
var selected = await context.tUniqueKeyStorages.FirstOrDefaultAsync(x => x.cIdentity == request.Identity);
if (selected != null)
{
selected.cData1 = request.Data1;
selected.cData2 = request.Data2;
selected.cData3 = request.Data3;
selected.cData4 = request.Data4;
selected.cData5 = request.Data5;
using (var transaction = await context.CreateTransactionAsync())
{
context.Update(selected);
transactionResult = await context.CloseTransactionAsync(transaction);
}
}
}
//db error
if (transactionResult == false)
{
response.Result = WebApiResult.Failed.ToString();
LogXnet.WriteLine($"Transaction Error::{guid}", LogXLabel.Error);
}
else
{
LogXnet.WriteLine($"Transaction Success", LogXLabel.DB);
}
}
}
}
return response;
}
private UniqueKeyDBContext? GetUniqueKeyDBContext(DbContextProvider provider, int dbID)
{
var connectionString = _configService?.GetConfig()?.DataBase?.Find(x => x.DBID == dbID);
return provider?.GetDBContext<UniqueKeyDBContext>($"{connectionString?.DBName}");
}
}
}

View File

@ -0,0 +1,28 @@
using System.Net;
using SystemX.Core.Communication;
namespace WebApi.Project.UniqueKeyApi.TaskManager
{
public class TaskSocket
{
//public async Task Run(int socketPort = 7777)
//{
// try
// {
// await Task.Delay(1000);
// Listener _listener = new Listener();
// IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, socketPort);
// _listener.Init(endPoint, () => { return SessionManager.Instance.Generate(); });
// Log4net.WriteLine($"Address:{endPoint.Address}, Port:{socketPort}", LogType.SOCKET);
// Log4net.WriteLine($"Socket Listening Start", LogType.SOCKET);
// }
// catch (Exception e)
// {
// Log4net.WriteLine("Socket Run Failed", LogType.Error);
// Log4net.WriteLine(e);
// }
//}
}
}

View File

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WebApi.Library\WebApi.Library.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="SystemX.Core">
<HintPath>..\..\DLL\SystemX.Core.dll</HintPath>
</Reference>
<Reference Include="SystemX.Core.DB">
<HintPath>..\..\DLL\SystemX.Core.DB.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
@WebApi.Project.UniqueKeyApi_HostAddress = http://localhost:5161
GET {{WebApi.Project.UniqueKeyApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

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

View File

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

View File

@ -10,8 +10,11 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{C8D5274F-AC00-46C7-1F8D-E88E81087A52}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{C8D5274F-AC00-46C7-1F8D-E88E81087A52}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
..\Config\WebApi.AuthApi.Config.json = ..\Config\WebApi.AuthApi.Config.json ..\Config\WebApi.AuthApi.Config.json = ..\Config\WebApi.AuthApi.Config.json
..\Config\WebApi.Project.UniqueKeyApi.Config.json = ..\Config\WebApi.Project.UniqueKeyApi.Config.json
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApi.Project.UniqueKeyApi", "WebApi.Project.UniqueKeyApi\WebApi.Project.UniqueKeyApi.csproj", "{3DDF6187-1294-48BC-B664-1C74AE73080A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -26,6 +29,10 @@ Global
{1B109CFE-B860-4125-8F2B-06D95DE85E91}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B109CFE-B860-4125-8F2B-06D95DE85E91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B109CFE-B860-4125-8F2B-06D95DE85E91}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B109CFE-B860-4125-8F2B-06D95DE85E91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B109CFE-B860-4125-8F2B-06D95DE85E91}.Release|Any CPU.Build.0 = Release|Any CPU {1B109CFE-B860-4125-8F2B-06D95DE85E91}.Release|Any CPU.Build.0 = Release|Any CPU
{3DDF6187-1294-48BC-B664-1C74AE73080A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DDF6187-1294-48BC-B664-1C74AE73080A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DDF6187-1294-48BC-B664-1C74AE73080A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3DDF6187-1294-48BC-B664-1C74AE73080A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE