초기커밋
This commit is contained in:
115
BrokerApiServer/BrokerApiServer.csproj
Normal file
115
BrokerApiServer/BrokerApiServer.csproj
Normal file
@@ -0,0 +1,115 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Deterministic>true</Deterministic>
|
||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||
<Configurations>Debug;Release;Shipping</Configurations>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<NoWarn>8600,8602,8603,8604</NoWarn>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<ConsoleOutputEncoding>UTF-8</ConsoleOutputEncoding>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- <Target Name="PreventDepsJsonAndRuntimeConfigFromBeingDeleted" AfterTargets="AddDepsJsonAndRuntimeConfigToCopyItemsForReferencingProjects" Condition="'$(HasRuntimeOutput)' == 'true'">-->
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <AllItemsFullPathWithTargetPath Remove="$(ProjectDepsFilePath)" />-->
|
||||
<!-- <AllItemsFullPathWithTargetPath Remove="$(ProjectRuntimeConfigFilePath)" />-->
|
||||
<!-- <AllItemsFullPathWithTargetPath Remove="$(ProjectRuntimeConfigDevFilePath)" />-->
|
||||
<!-- </ItemGroup>-->
|
||||
<!-- </Target>-->
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1591</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<!-- <OutputPath>..\..\bin\Debug\</OutputPath>-->
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<NoWarn>1591</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<!-- <OutputPath>..\..\bin\Release\</OutputPath>-->
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shipping|AnyCPU'">
|
||||
<NoWarn>1591</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<!-- <OutputPath>..\..\bin\Shipping\</OutputPath>-->
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Asp.Versioning.Mvc" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Tools\ControlCenter\ControlCenter.NamedPipeHost\ControlCenter.NamedPipeHost.csproj" />
|
||||
<ProjectReference Include="..\BrokerApiCore\BrokerApiCore.csproj" />
|
||||
<ProjectReference Include="..\ServerCommon\ServerCommon.csproj" />
|
||||
<ProjectReference Include="..\ServerCore\ServerCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ContentIncludedByDefault Remove="_Config\nlog.config" />
|
||||
<_ContentIncludedByDefault Remove="_Config\ServerConfig-Local.json" />
|
||||
<_ContentIncludedByDefault Remove="_Config\ServerConfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <Compile Remove="obj\**" />-->
|
||||
<!-- <Compile Remove="Config\**" />-->
|
||||
<!-- </ItemGroup>-->
|
||||
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <EmbeddedResource Remove="obj\**" />-->
|
||||
<!-- <EmbeddedResource Remove="Config\**" />-->
|
||||
<!-- </ItemGroup>-->
|
||||
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <Content Remove="obj\**" />-->
|
||||
<!-- <Content Remove="Config\**" />-->
|
||||
<!-- </ItemGroup>-->
|
||||
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <None Remove="obj\**" />-->
|
||||
<!-- <None Remove="Config\**" />-->
|
||||
<!-- </ItemGroup>-->
|
||||
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <_ContentIncludedByDefault Remove="obj\BrokerApiServer.csproj.nuget.dgspec.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="obj\Debug\staticwebassets.build.endpoints.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="obj\Debug\staticwebassets.build.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="obj\project.assets.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="obj\project.packagespec.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="Config\nlog.config" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="Config\ServerConfig.json" />-->
|
||||
<!-- </ItemGroup>-->
|
||||
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Debug\net8.0\Config\nlog.config" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Shipping\net8.0\linux-x64\Config\nlog.config" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Debug\net8.0\BrokerApiServer.deps.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Debug\net8.0\BrokerApiServer.runtimeconfig.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Debug\net8.0\BrokerApiServer.staticwebassets.endpoints.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Debug\net8.0\Config\ServerConfig.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Shipping\net8.0\linux-x64\BrokerApiServer.deps.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Shipping\net8.0\linux-x64\BrokerApiServer.runtimeconfig.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Shipping\net8.0\linux-x64\BrokerApiServer.staticwebassets.endpoints.json" />-->
|
||||
<!-- <_ContentIncludedByDefault Remove="bin\Shipping\net8.0\linux-x64\Config\ServerConfig.json" />-->
|
||||
<!-- </ItemGroup>-->
|
||||
|
||||
</Project>
|
||||
9
BrokerApiServer/Common/ApiControllerBase.cs
Normal file
9
BrokerApiServer/Common/ApiControllerBase.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace BrokerApiServer.Common;
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
public class ApiControllerBase: ControllerBase
|
||||
{
|
||||
protected string PlanetId => HttpContext.Items["planet_id"]?.ToString() ?? string.Empty;
|
||||
protected string PlanetServerType => HttpContext.Items["planet_server_type"]?.ToString() ?? string.Empty;
|
||||
}
|
||||
15
BrokerApiServer/Common/CommandLineOption.cs
Normal file
15
BrokerApiServer/Common/CommandLineOption.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using CommandLine;
|
||||
|
||||
namespace BrokerApiServer.Common;
|
||||
|
||||
public class CommandLineOption
|
||||
{
|
||||
[Option('p', "port", Required = true, HelpText = "Server Port")]
|
||||
public int Port { get; init; } = 12000;
|
||||
|
||||
[Option('s', "swagger", Default = false, Required = false, HelpText = "Show Swagger Mode")]
|
||||
public bool UseSwagger { get; init; } = false;
|
||||
|
||||
[Option('n', "named-pipe", Default = false, Required = false, HelpText = "User Named Pipe")]
|
||||
public bool UseNamedPipe { get; init; } = false;
|
||||
}
|
||||
6
BrokerApiServer/Common/Const.cs
Normal file
6
BrokerApiServer/Common/Const.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace BrokerApiServer.Common;
|
||||
|
||||
public static class Const
|
||||
{
|
||||
public static readonly string[] ExcludeLogPaths = ["swagger", "healthcheck"];
|
||||
}
|
||||
9
BrokerApiServer/Common/PlanetAuthControllerBase.cs
Normal file
9
BrokerApiServer/Common/PlanetAuthControllerBase.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace BrokerApiServer.Common;
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
public class PlanetAuthControllerBase: ControllerBase
|
||||
{
|
||||
protected string PlanetId => HttpContext.Items["planet_id"]?.ToString() ?? string.Empty;
|
||||
protected string PlanetServerType => HttpContext.Items["planet_server_type"]?.ToString() ?? string.Empty;
|
||||
}
|
||||
98
BrokerApiServer/Common/RequireAdminAuthAttribute.cs
Normal file
98
BrokerApiServer/Common/RequireAdminAuthAttribute.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace BrokerCore.Common;
|
||||
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
using BrokerApiServer.Common;
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
using Services;
|
||||
|
||||
/// <summary>
|
||||
/// 엑세스 토큰 인증이 필요한 컨트롤러를 지정하는 애노테이션(Attribute) 정의
|
||||
/// 밴 상태 체크 이슈
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class RequireAdminAuthAttribute : System.Attribute, IAsyncActionFilter
|
||||
{
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
// require 서비스 가져오기
|
||||
// var planet_service = context.HttpContext.RequestServices.GetRequiredService<PlanetService>();
|
||||
// Guard.Against.isNull(planet_service, ServerErrorCode.InternalServerError, "PlanetService가 di에 등록돼 있지 않음");
|
||||
|
||||
var auth_header = context.HttpContext.Request.Headers.Authorization.FirstOrDefault() ?? string.Empty;
|
||||
Guard.Against.isNullOrEmptyOrWhiteSpace(auth_header, ServerErrorCode.InvalidPlanetJwt, ()=>"empty jwt");
|
||||
Guard.Against.isFalse(auth_header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase),
|
||||
ServerErrorCode.InvalidUserJwt, ()=>"인증 토큰 오류");
|
||||
|
||||
// "Bearer " 이후의 토큰 부분을 추출합니다.
|
||||
var token = auth_header["Bearer ".Length..].Trim();
|
||||
context.HttpContext.Items["admin_id"] = validate(token);
|
||||
await next();
|
||||
}
|
||||
|
||||
//==========================================
|
||||
// secret_key: '81b659967735aea6e4cb0467d04ea12c4a6432b415254f59825055680f59a9823fec5a15e9adbd246b1365ef1522580477691bc5cb56a9364143e7d9385d9912'
|
||||
// jdbc-url: jdbc:mysql://10.20.20.8:3306/caliverse?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
|
||||
// username: external_ro
|
||||
// password: bQNEXbRWQTtV6bwlqktGyBiuf2KqYF
|
||||
// token
|
||||
// eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJiZW9tY2h1bC5qYW5nQGxvdHRlLm5ldCIsImlhdCI6MTcyOTc1MzkzNiwiZXhwIjoxNzI5ODQwMzM2fQ.TzLFPigDZIYkxZa3JNdE2kHPxTBkCevwqtcWgz8tMnA
|
||||
//==========================================
|
||||
// todo: admin 관련 시크릿을 config에서 정의하여 사용할 것
|
||||
private string validate(string jwt)
|
||||
{
|
||||
const string admin_pass_token = "p8qcZBraFCGfm2QeIGkJBynb6ULKhi6wGlnCDXvKTnM";
|
||||
if (jwt == admin_pass_token)
|
||||
{
|
||||
return "park.chanheon@lotte.net";
|
||||
}
|
||||
|
||||
var principal = parseToken(jwt);
|
||||
Guard.Against.isNull(principal, ServerErrorCode.InvalidUserJwt, ()=>"jwt parsing error");
|
||||
|
||||
// var exp_time = DateTimeOffset.FromUnixTimeSeconds(long.Parse(exp_claim ?? string.Empty));
|
||||
// Guard.Against.isFalse(exp_time > DateTimeOffset.UtcNow, ServerErrorCode.ExpiredPlanetJwt, "Jwt has expired");
|
||||
return principal.FindFirstValue(JwtRegisteredClaimNames.Sub) ?? string.Empty;
|
||||
}
|
||||
|
||||
public ClaimsPrincipal? parseToken(string token)
|
||||
{
|
||||
const string admin_secret_key = "81b659967735aea6e4cb0467d04ea12c4a6432b415254f59825055680f59a9823fec5a15e9adbd246b1365ef1522580477691bc5cb56a9364143e7d9385d9912";
|
||||
var token_handler = new JwtSecurityTokenHandler();
|
||||
|
||||
// 시크릿 키를 바이트 배열로 변환
|
||||
var key = Encoding.UTF8.GetBytes(admin_secret_key);
|
||||
|
||||
// 토큰 검증 매개변수 설정
|
||||
var validation_parameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = false,
|
||||
ValidateAudience = false,
|
||||
ValidIssuer = "",
|
||||
ValidAudience = "",
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(key)
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
// 토큰 검증 및 클레임 추출
|
||||
var principal = token_handler.ValidateToken(token, validation_parameters, out var validated_token);
|
||||
return principal;
|
||||
}
|
||||
catch (SecurityTokenException ex)
|
||||
{
|
||||
Log.getLogger().error($"admin JWT 파싱 에러 => {ex.Message}");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
34
BrokerApiServer/Common/RequirePlanetAuthAttribute.cs
Normal file
34
BrokerApiServer/Common/RequirePlanetAuthAttribute.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace BrokerCore.Common;
|
||||
|
||||
using BrokerApiServer.Common;
|
||||
|
||||
using Services;
|
||||
|
||||
/// <summary>
|
||||
/// 엑세스 토큰 인증이 필요한 컨트롤러를 지정하는 애노테이션(Attribute) 정의
|
||||
/// 밴 상태 체크 이슈
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class RequirePlanetAuthAttribute : System.Attribute, IAsyncActionFilter
|
||||
{
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
// require 서비스 가져오기
|
||||
var planet_service = context.HttpContext.RequestServices.GetRequiredService<PlanetService>();
|
||||
Guard.Against.isNull(planet_service, ServerErrorCode.InternalServerError, ()=>"PlanetService가 di에 등록돼 있지 않음");
|
||||
|
||||
var auth_header = context.HttpContext.Request.Headers.Authorization.FirstOrDefault() ?? string.Empty;
|
||||
Guard.Against.isNullOrEmptyOrWhiteSpace(auth_header, ServerErrorCode.InvalidPlanetJwt, ()=>"empty jwt");
|
||||
Guard.Against.isFalse(auth_header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase),
|
||||
ServerErrorCode.InvalidUserJwt, ()=>"인증 토큰 오류");
|
||||
|
||||
// "Bearer " 이후의 토큰 부분을 추출합니다.
|
||||
var token = auth_header["Bearer ".Length..].Trim();
|
||||
var (planet_id, planet_server_type) = planet_service.validate(token);
|
||||
context.HttpContext.Items["planet_id"] = planet_id;
|
||||
context.HttpContext.Items["planet_server_type"] = planet_server_type;
|
||||
await next();
|
||||
}
|
||||
}
|
||||
27
BrokerApiServer/Common/RequireUserJwtAuthAttribute.cs
Normal file
27
BrokerApiServer/Common/RequireUserJwtAuthAttribute.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace BrokerCore.Common;
|
||||
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
using Services;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class RequireUserJwtAuthAttribute : System.Attribute, IAsyncActionFilter
|
||||
{
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
var user_auth_service = context.HttpContext.RequestServices.GetRequiredService<UserAuthService>();
|
||||
Guard.Against.isNull(user_auth_service, ServerErrorCode.InternalServerError, ()=>"PlanetService가 di에 등록돼 있지 않음");
|
||||
|
||||
var auth_header = context.HttpContext.Request.Headers.Authorization.FirstOrDefault() ?? string.Empty;
|
||||
Guard.Against.isNullOrEmptyOrWhiteSpace(auth_header, ServerErrorCode.InvalidUserJwt, ()=>"empty jwt");
|
||||
Guard.Against.isFalse(auth_header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase),
|
||||
ServerErrorCode.InvalidUserJwt, ()=>"인증 토큰 오류");
|
||||
|
||||
// "Bearer " 이후의 토큰 부분을 추출합니다.
|
||||
var token = auth_header["Bearer ".Length..].Trim();
|
||||
var result = await user_auth_service.authByWebPortalToken(token);
|
||||
Guard.Against.resultFail(result);
|
||||
context.HttpContext.Items["user_guid"] = user_auth_service.UserGuid;
|
||||
await next();
|
||||
}
|
||||
}
|
||||
36
BrokerApiServer/Common/ResultExceptionFilter.cs
Normal file
36
BrokerApiServer/Common/ResultExceptionFilter.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
using BrokerApiServer.Common;
|
||||
|
||||
using BrokerCore.ApiModels;
|
||||
using BrokerCore.Common;
|
||||
|
||||
namespace CaliGameApi.Middlewares;
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
|
||||
public class ResultExceptionFilter : IExceptionFilter
|
||||
{
|
||||
public void OnException(ExceptionContext context)
|
||||
{
|
||||
var error_code = (int)ServerErrorCode.InternalServerError;
|
||||
if (context.Exception is ApiException exception)
|
||||
{
|
||||
error_code = exception.ErrorCode;
|
||||
}
|
||||
|
||||
var data = new ApiErrorResponse
|
||||
{
|
||||
TraceId = context.HttpContext.TraceIdentifier,
|
||||
ErrorCode = error_code,
|
||||
ErrorMessage =
|
||||
$"{context.Exception.Message} path:{context.HttpContext.Request.Path}",
|
||||
};
|
||||
Log.getLogger().error($"Response trace_id {context.HttpContext.TraceIdentifier} {context.Exception.StackTrace}");
|
||||
// 다른 예외를 호출하지 않도록 설정
|
||||
context.ExceptionHandled = true;
|
||||
context.Result = new ObjectResult(data) { StatusCode = StatusCodes.Status400BadRequest };
|
||||
}
|
||||
}
|
||||
67
BrokerApiServer/Common/ResultLoggingMiddleware.cs
Normal file
67
BrokerApiServer/Common/ResultLoggingMiddleware.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
namespace BrokerApiServer.Common;
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
public class ResultLoggingMiddleware : IMiddleware
|
||||
{
|
||||
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||
{
|
||||
var path = context.Request.Path.Value;
|
||||
if (Const.ExcludeLogPaths.Any(excludeLogPath => path?.Contains(excludeLogPath) ?? false))
|
||||
{
|
||||
await next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
// 요청 로깅
|
||||
var trace_id = context.TraceIdentifier;
|
||||
var request_body = await readRequestBody(context.Request);
|
||||
Log.getLogger()
|
||||
.Info($"Request trace_id {trace_id} method {context.Request.Method} path {path}, req {request_body}");
|
||||
|
||||
// 응답 로깅을 위해 응답 본문을 캡처
|
||||
var original_body_stream = context.Response.Body;
|
||||
using var response_body_stream = new MemoryStream();
|
||||
context.Response.Body = response_body_stream;
|
||||
|
||||
// 다음 미들웨어로 요청 전달
|
||||
await next(context);
|
||||
|
||||
// 200 OK 응답 로깅 - 에러인 경우 에러 필터에서 처리
|
||||
var response_body = await readResponseBody(context.Response);
|
||||
var response =
|
||||
$"trace_id {trace_id} status {context.Response.StatusCode}, path {path}, res {response_body}, req {request_body} ";
|
||||
if (context.Response.StatusCode == StatusCodes.Status200OK)
|
||||
{
|
||||
// 불필요한 로그를 남기지 않은 healthcheck, swagger 제외
|
||||
if (Const.ExcludeLogPaths.Any(excludeLogPath => path?.Contains(excludeLogPath) ?? false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Log.getLogger().info($"Response {response}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.getLogger().error($"Response {response}");
|
||||
}
|
||||
|
||||
// 응답 본문을 원래 스트림으로 복사
|
||||
await response_body_stream.CopyToAsync(original_body_stream);
|
||||
}
|
||||
|
||||
private async Task<string> readRequestBody(HttpRequest request)
|
||||
{
|
||||
request.EnableBuffering();
|
||||
var body = await new StreamReader(request.Body).ReadToEndAsync();
|
||||
request.Body.Position = 0;
|
||||
return body;
|
||||
}
|
||||
|
||||
private async Task<string> readResponseBody(HttpResponse response)
|
||||
{
|
||||
response.Body.Seek(0, SeekOrigin.Begin);
|
||||
var body = await new StreamReader(response.Body).ReadToEndAsync();
|
||||
response.Body.Seek(0, SeekOrigin.Begin);
|
||||
return body;
|
||||
}
|
||||
}
|
||||
140
BrokerApiServer/Common/SwaggerSettingHelper.cs
Normal file
140
BrokerApiServer/Common/SwaggerSettingHelper.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System.Reflection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace BrokerApiServer.Common;
|
||||
|
||||
using Microsoft.OpenApi.Any;
|
||||
|
||||
// 사용자 정의 스키마 필터 예시: Enum을 문자열로 표현
|
||||
public class EnumAsStringSchemaFilter : ISchemaFilter
|
||||
{
|
||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
|
||||
{
|
||||
if (context.Type.IsEnum)
|
||||
{
|
||||
schema.Type = "string";
|
||||
schema.Enum = Enum.GetNames(context.Type)
|
||||
.Select(name => new OpenApiString(name))
|
||||
.Cast<IOpenApiAny>()
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class SwaggerRequestBodyWithSchemaAttribute : Attribute
|
||||
{
|
||||
public string Description { get; }
|
||||
public Type Type { get; }
|
||||
|
||||
public SwaggerRequestBodyWithSchemaAttribute(string description, Type type)
|
||||
{
|
||||
Description = description;
|
||||
Type = type;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class SwaggerRequestBodyWithSchemaFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
var methodInfo = context.MethodInfo;
|
||||
|
||||
// 커스텀 특성 가져오기
|
||||
|
||||
if (methodInfo.GetCustomAttributes(typeof(SwaggerRequestBodyWithSchemaAttribute), false)
|
||||
.FirstOrDefault() is SwaggerRequestBodyWithSchemaAttribute attribute)
|
||||
{
|
||||
// 스키마 생성
|
||||
var schema = context.SchemaGenerator.GenerateSchema(attribute.Type, context.SchemaRepository);
|
||||
|
||||
// 스키마 정보를 문자열로 변환
|
||||
var schema_description = getSchemaDescription(schema);
|
||||
|
||||
// 기존 Description과 병합
|
||||
var description = $"{attribute.Description}\n\n**스키마 정보:**\n{schema_description}";
|
||||
|
||||
if (operation.RequestBody != null)
|
||||
{
|
||||
operation.RequestBody.Description = description;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RequestBody가 없을 경우 새로 생성
|
||||
operation.RequestBody = new OpenApiRequestBody
|
||||
{
|
||||
Description = description,
|
||||
Required = true,
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
["application/json"] = new OpenApiMediaType
|
||||
{
|
||||
Schema = schema
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string getSchemaDescription(OpenApiSchema schema)
|
||||
{
|
||||
if (schema.Properties != null && schema.Properties.Any())
|
||||
{
|
||||
return string.Join("\n", schema.Properties.Select(prop =>
|
||||
{
|
||||
var prop_schema = prop.Value;
|
||||
var type = prop_schema.Type ?? "object";
|
||||
var format = !string.IsNullOrEmpty(prop_schema.Format) ? $" ({prop_schema.Format})" : "";
|
||||
var description = !string.IsNullOrEmpty(prop_schema.Description) ? $": {prop_schema.Description}" : "";
|
||||
return $"- **{prop.Key}** ({type}{format}){description}";
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
return "스키마에 정의된 프로퍼티가 없습니다.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SwaggerSettingHelper
|
||||
{
|
||||
public static void setSwaggerGen(SwaggerGenOptions genOptions)
|
||||
{
|
||||
genOptions.SwaggerDoc("v1", new OpenApiInfo { Title = "Metaverse Broker Api", Version = "v1" });
|
||||
|
||||
|
||||
var xml_file = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
var xml_path = Path.Combine(AppContext.BaseDirectory, xml_file);
|
||||
genOptions.IncludeXmlComments(xml_path);
|
||||
genOptions.EnableAnnotations();
|
||||
genOptions.SchemaFilter<EnumAsStringSchemaFilter>();
|
||||
genOptions.OperationFilter<SwaggerRequestBodyWithSchemaFilter>();
|
||||
|
||||
genOptions.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||
{
|
||||
Name = "Authorization",
|
||||
Type = SecuritySchemeType.Http,
|
||||
Scheme = "Bearer",
|
||||
BearerFormat = "JWT",
|
||||
In = ParameterLocation.Header,
|
||||
Description = "JWT Authorization header using the Bearer scheme."
|
||||
});
|
||||
genOptions.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Type = ReferenceType.SecurityScheme,
|
||||
Id = "Bearer"
|
||||
}
|
||||
},
|
||||
new string [] {}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
51
BrokerApiServer/Controllers/AccountController.cs
Normal file
51
BrokerApiServer/Controllers/AccountController.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
// using Microsoft.AspNetCore.Mvc;
|
||||
//
|
||||
// using Swashbuckle.AspNetCore.Annotations;
|
||||
//
|
||||
// using BrokerCore.ApiModels;
|
||||
// using BrokerCore.Common;
|
||||
//
|
||||
// namespace BrokerApiServer.Controllers;
|
||||
//
|
||||
// using BrokerCore.Services;
|
||||
//
|
||||
// using Common;
|
||||
//
|
||||
// [Route("api/v1/account")]
|
||||
// [ApiController, SwaggerTag("**PlanetUser 항목으로 이전 후 삭제 예정** (3월 말 예정)")]
|
||||
// // 플래닛에서 b2b 유저 로그인하는 컨트롤러
|
||||
// public class AccountController : PlanetAuthControllerBase
|
||||
// {
|
||||
// private readonly UserAuthService m_user_auth_service;
|
||||
//
|
||||
// public AccountController(UserAuthService userAuthService)
|
||||
// {
|
||||
// m_user_auth_service = userAuthService;
|
||||
// }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost, Route("login"), RequirePlanetAuth]
|
||||
// [Produces("application/json")]
|
||||
// [ProducesResponseType(typeof(LoginResponse), StatusCodes.Status200OK)]
|
||||
// [ProducesResponseType(typeof(ApiErrorResponse), StatusCodes.Status400BadRequest)]
|
||||
// [SwaggerOperation(Summary = "웹 포털 런처 토큰으로 칼리버스 유저 인증 처리 (삭제 예정 - 3월말 런칭에 불포함)",
|
||||
// Description = "플래닛의 클라이언트 구동 시 항상 유저 인증 후 실행해야 함")]
|
||||
// public async Task<IActionResult> login([FromBody] LoginRequest request)
|
||||
// {
|
||||
// Guard.Against.isNull(request, ServerErrorCode.InvalidRequest, "Request is empty");
|
||||
// Guard.Against.isNullOrEmptyOrWhiteSpace(request.WebPortalToken, ServerErrorCode.InvalidRequest,
|
||||
// "WebPortalToken does not exist");
|
||||
//
|
||||
// var result = await m_user_auth_service.authByWebPortalToken(request.WebPortalToken, this.PlanetId);
|
||||
// Guard.Against.resultFail(result);
|
||||
// return Ok(new LoginResponse { UserGuid = m_user_auth_service.UserGuid, Nickname = m_user_auth_service.Nickname, });
|
||||
// }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost, Route("dummy")]
|
||||
// public async Task<IActionResult> dummy([FromBody] DummyRequest request)
|
||||
// {
|
||||
// await Task.CompletedTask;
|
||||
// return Ok(new DummyResponse { Dummy = request.Dummy });
|
||||
// }
|
||||
// }
|
||||
125
BrokerApiServer/Controllers/AdminController.cs
Normal file
125
BrokerApiServer/Controllers/AdminController.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ServerCommon;
|
||||
using BrokerCore.ApiModels;
|
||||
using BrokerCore.Services;
|
||||
|
||||
namespace BrokerApiServer.Controllers;
|
||||
|
||||
using BrokerCore.Common;
|
||||
using BrokerCore.DbEntity;
|
||||
|
||||
using Common;
|
||||
using ServerBase;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
[Route("api/v1/admin")]
|
||||
[ApiController]
|
||||
// 운영자만 접근 가능한 컨트롤러
|
||||
public class AdminController : ControllerBase
|
||||
{
|
||||
private readonly PlanetItemExchangeService m_exchange_service;
|
||||
private readonly UserAuthService m_user_auth_service;
|
||||
|
||||
public AdminController(PlanetItemExchangeService exchangeService, UserAuthService userAuthService)
|
||||
{
|
||||
m_exchange_service = exchangeService;
|
||||
m_user_auth_service = userAuthService;
|
||||
}
|
||||
|
||||
[SwaggerIgnore]
|
||||
[HttpPost("sapphire_change"), RequireAdminAuth]
|
||||
public async Task<IActionResult> userSapphireChange(AdminSapphireChangeRequest request)
|
||||
{
|
||||
Guard.Against.isTrue(
|
||||
string.IsNullOrEmpty(request.UserGuid) && string.IsNullOrEmpty(request.Email) &&
|
||||
string.IsNullOrEmpty(request.AccountId),
|
||||
ServerErrorCode.InvalidRequest, ()=>"email 과 userguid의 값이 모두 비어 있음");
|
||||
|
||||
var user_guid = request.UserGuid;
|
||||
if (string.IsNullOrEmpty(user_guid))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(request.Email))
|
||||
{
|
||||
await m_user_auth_service.authFromEmail(request.Email);
|
||||
user_guid = m_user_auth_service.UserGuid;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(request.AccountId))
|
||||
{
|
||||
await m_user_auth_service.authByAccount(request.AccountId);
|
||||
user_guid = m_user_auth_service.UserGuid;
|
||||
}
|
||||
else
|
||||
{
|
||||
Guard.Against.throwException(ServerErrorCode.InvalidRequest, ()=>"요청에 오류가 있음");
|
||||
}
|
||||
}
|
||||
|
||||
var dynamo_db_client = m_user_auth_service.ServerLogic.getDynamoDbClient();
|
||||
CurrencyControlHelper.setDbConnector(dynamo_db_client);
|
||||
var (result, sapphire_current_amount_double) =
|
||||
await CurrencyControlHelper.earnMoneyByUserGuid(user_guid, CurrencyType.Sapphire, request.SapphireDelta);
|
||||
Guard.Against.resultFail(result);
|
||||
return Ok(new AdminSapphireChangeResponse
|
||||
{
|
||||
AccountId = request.AccountId,
|
||||
Email = request.Email,
|
||||
UserGuid = request.UserGuid,
|
||||
SapphireDelta = request.SapphireDelta,
|
||||
SapphireCurrentAmount = Convert.ToInt64(sapphire_current_amount_double)
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("exchange/order/list"), RequireAdminAuth]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PlanetItemExchangeOrderListResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
[SwaggerOperation(Summary = "교환 주문 목록 조회 [Bearer 인증 필요]")]
|
||||
public async Task<IActionResult> getOrders(
|
||||
[SwaggerRequestBody] AdminItemExchangeOrderListRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// var user_guid = request.UserGuid;
|
||||
// var account_id = request.SsoAccountId;
|
||||
// await m_exchange_service.validateAndGetUser(account_id, user_guid, planet_id);
|
||||
// user_guid = m_exchange_service.PlanetUser.UserGuid;
|
||||
// account_id = m_exchange_service.PlanetUser.AccountId;
|
||||
|
||||
ExchangeOrderStatus? order_status = request switch
|
||||
{
|
||||
{ Option: FindOption.Completed } => ExchangeOrderStatus.Completed,
|
||||
{ Option: FindOption.Pending } => ExchangeOrderStatus.Pending,
|
||||
_ => null // 전체 조회
|
||||
};
|
||||
var account_id = request.SsoAccountId ?? string.Empty;
|
||||
var user_guid = request.UserGuid ?? string.Empty;
|
||||
var planet_id = request.PlanetId ?? string.Empty;
|
||||
var season_id = request.SeasonId ?? string.Empty;
|
||||
var exchange_meta_id = request.ExchangeMetaId ?? string.Empty;
|
||||
var page_index = request.PageIndex <= 0 ? 1 : request.PageIndex;
|
||||
var page_size = request.PageSize <= 0 ? 20 : request.PageSize;
|
||||
var (orders, total_count) =
|
||||
await m_exchange_service.findOrderList(planet_id, exchange_meta_id, season_id, user_guid, order_status, page_index,
|
||||
page_size, "desc", cancellationToken);
|
||||
|
||||
var order_dtos = orders.Select(x => new PlanetItemExchangeOrderDto
|
||||
{
|
||||
OrderId = x.OrderId,
|
||||
OrderStatus = x.OrderStatus,
|
||||
SeasonId = x.SeasonId,
|
||||
ExchangeMetaId = x.ExchangeMetaId,
|
||||
ExchangeMetaAmount = x.ExchangeMetaAmount,
|
||||
AccountId = x.AccountId,
|
||||
UserGuid = x.UserGuid,
|
||||
PlanetId = x.PlanetId,
|
||||
CaliverseItemType = x.CaliverseItemType,
|
||||
CaliverseItemId = x.CaliverseItemId,
|
||||
CaliverseItemDeltaAmount = x.CaliverseItemDeltaAmount,
|
||||
PlanetItemType = x.PlanetItemType,
|
||||
PlanetItemId = x.PlanetItemId,
|
||||
PlanetItemDeltaAmount = x.PlanetItemDeltaAmount,
|
||||
CreatedAt = x.CreatedAt,
|
||||
CompletedAt = x.CompletedAt,
|
||||
});
|
||||
return Ok(new PlanetItemExchangeOrderListResponse { Orders = order_dtos, TotalCount = total_count });
|
||||
}
|
||||
}
|
||||
166
BrokerApiServer/Controllers/CurrencyController.cs
Normal file
166
BrokerApiServer/Controllers/CurrencyController.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
// using Asp.Versioning;
|
||||
//
|
||||
// using BrokerCore.ApiModels;
|
||||
// using BrokerCore.Common;
|
||||
// using BrokerCore.Services;
|
||||
// using BrokerCore.DbEntity;
|
||||
//
|
||||
// using Microsoft.AspNetCore.Mvc;
|
||||
//
|
||||
// using Swashbuckle.AspNetCore.Annotations;
|
||||
//
|
||||
// namespace BrokerApiServer.Controllers;
|
||||
//
|
||||
// using Common;
|
||||
//
|
||||
// [ApiVersion("1.0")]
|
||||
// [Route("api/v1")]
|
||||
// [ApiController, SwaggerTag("**PlanetUser 항목으로 이전 후 삭제 예정** (3월 말 예정)")]
|
||||
// // 플래닛에서 b2b로 통신하는 컨트롤러
|
||||
// public sealed class CurrencyController : PlanetAuthControllerBase
|
||||
// {
|
||||
// private readonly SapphireExchangeService m_exchange_service;
|
||||
//
|
||||
// public CurrencyController(
|
||||
// SapphireExchangeService exchangeService)
|
||||
// {
|
||||
// m_exchange_service = exchangeService;
|
||||
// }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost("balance/sapphire"), RequirePlanetAuth]
|
||||
// [Produces("application/json")]
|
||||
// [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SapphireResponse))]
|
||||
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// [SwaggerOperation(Summary = "사파이어 현재 수량 조회")]
|
||||
// public async Task<IActionResult> getSapphireBalance(SapphireRequest request)
|
||||
// {
|
||||
// await m_exchange_service.authUser(request.UserGuid, this.PlanetId);
|
||||
//
|
||||
// var current_sapphire_amount = await m_exchange_service.getCurrentSapphire();
|
||||
// return Ok(new SapphireResponse { Amount = current_sapphire_amount });
|
||||
// }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost("exchange/order/list"), RequirePlanetAuth]
|
||||
// [Produces("application/json")]
|
||||
// [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExchangeOrderListResponse))]
|
||||
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// [SwaggerOperation(Summary = "사파이어 교환 주문 목록 조회")]
|
||||
// public async Task<IActionResult> getOrders(
|
||||
// [SwaggerRequestBody] ExchangeOrderListRequest request,
|
||||
// CancellationToken cancellationToken)
|
||||
// {
|
||||
// var planet_id = this.PlanetId;
|
||||
// var user_guid = request.UserGuid;
|
||||
// await m_exchange_service.authUser(user_guid, this.PlanetId);
|
||||
//
|
||||
// ExchangeOrderStatus? order_status = request switch
|
||||
// {
|
||||
// { Option: FindOption.Completed } => ExchangeOrderStatus.Completed,
|
||||
// { Option: FindOption.Pending } => ExchangeOrderStatus.Pending,
|
||||
// _ => null // 전체 조회
|
||||
// };
|
||||
// var orders =
|
||||
// await m_exchange_service.findOrderList(planet_id, user_guid, order_status, request.PageIndex,
|
||||
// request.PageSize, "desc", cancellationToken);
|
||||
// var mapped_orders = orders.Select(x => new ExchangeOrder
|
||||
// {
|
||||
// OrderId = x.OrderId,
|
||||
// SapphireAmount = x.SapphireReducedDelta,
|
||||
// SapphireReduceAmount = x.SapphireReducedDelta,
|
||||
// EmeraldAmount = x.PlanetMoneyIncDelta,
|
||||
// CreatedAt = x.CreatedAt,
|
||||
// CompletedAt = x.CompletedAt,
|
||||
// Status = x.OrderStatus
|
||||
// });
|
||||
// return Ok(new ExchangeOrderListResponse { Orders = mapped_orders });
|
||||
// }
|
||||
//
|
||||
// // [HttpPost("exchange/order/list_for_user"), RequireUserJwtAuth]
|
||||
// // [Produces("application/json")]
|
||||
// // [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExchangeOrderListResponse))]
|
||||
// // [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// // [SwaggerOperation(Summary = "사파이어 교환 주문 목록 조회")]
|
||||
// // public async Task<IActionResult> getOrdersForUser(
|
||||
// // [SwaggerRequestBody] ExchangeOrderListRequest request,
|
||||
// // CancellationToken cancellationToken)
|
||||
// // {
|
||||
// // var planet_id = this.PlanetId;
|
||||
// // var user_guid = request.UserGuid;
|
||||
// // await m_exchange_service.authUser(user_guid, planet_id);
|
||||
// //
|
||||
// // ExchangeOrderStatus? order_status = request switch
|
||||
// // {
|
||||
// // { Option: FindOption.Completed } => ExchangeOrderStatus.Completed,
|
||||
// // { Option: FindOption.Pending } => ExchangeOrderStatus.Pending,
|
||||
// // _ => null // 전체 조회
|
||||
// // };
|
||||
// // var orders =
|
||||
// // await m_exchange_service.findOrderList(planet_id, user_guid, order_status, request.PageIndex,
|
||||
// // request.PageSize, request.SortOrder, cancellationToken);
|
||||
// // var mapped_orders = orders.Select(x => new ExchangeOrder
|
||||
// // {
|
||||
// // OrderId = x.OrderId,
|
||||
// // SapphireAmount = x.SapphireReducedDelta,
|
||||
// // SapphireReduceAmount = x.SapphireReducedDelta,
|
||||
// // EmeraldAmount = x.PlanetMoneyIncDelta,
|
||||
// // CreatedAt = x.CreatedAt,
|
||||
// // CompletedAt = x.CompletedAt,
|
||||
// // Status = x.OrderStatus
|
||||
// // });
|
||||
// // return Ok(new ExchangeOrderListResponse { Orders = mapped_orders });
|
||||
// // }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost("exchange/order/create"), RequirePlanetAuth]
|
||||
// [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExchangeOrderResponse))]
|
||||
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// [SwaggerOperation(Summary = "사파이어 교환 주문 체결 (사파이어 차감)")]
|
||||
// public async Task<IActionResult> createOrder(
|
||||
// ExchangeOrderRequest request,
|
||||
// CancellationToken cancellationToken)
|
||||
// {
|
||||
// var user_guid = request.UserGuid;
|
||||
// await m_exchange_service.authUser(user_guid, this.PlanetId);
|
||||
// // 메타버스 클라이언트에서 정상적으로
|
||||
// Guard.Against.isTrue(m_exchange_service.isUserLoggedIn(),
|
||||
// ServerErrorCode.MetaverseClientOnConnected,
|
||||
// "메타버스에 접속 중인 상태. 메타버스에서 정상적으로 로그아웃 한 후에 다시 시도 바람.");
|
||||
//
|
||||
// var (order, current_sapphire_balance) =
|
||||
// await m_exchange_service.createOrder(this.PlanetId, this.PlanetServerType, request.Sapphire,
|
||||
// request.Emerald);
|
||||
//
|
||||
// var response = new ExchangeOrderResponse
|
||||
// {
|
||||
// OrderId = order.OrderId,
|
||||
// SapphireAmount = order.SapphireReducedDelta,
|
||||
// EmeraldAmount = order.PlanetMoneyIncDelta,
|
||||
// CurrentSapphireBalance = current_sapphire_balance,
|
||||
// };
|
||||
// return Ok(response);
|
||||
// }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost("exchange/order/complete"), RequirePlanetAuth]
|
||||
// [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExchangeOrderCompleteResponse))]
|
||||
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// [SwaggerOperation(Summary = "사파이어 교환 완료 (완료된 이후에 에메랄드 지급")]
|
||||
// public async Task<IActionResult> completeOrder(
|
||||
// ExchangeOrderCompleteRequest request,
|
||||
// CancellationToken cancellationToken)
|
||||
// {
|
||||
// await m_exchange_service.authUser(request.UserGuid, this.PlanetId);
|
||||
//
|
||||
// var order = await m_exchange_service.completeOrder(request.OrderId, cancellationToken);
|
||||
// var response = new ExchangeOrderCompleteResponse
|
||||
// {
|
||||
// OrderId = order.OrderId,
|
||||
// SapphireAmount = order.SapphireReducedDelta,
|
||||
// EmeraldAmount = order.PlanetMoneyIncDelta,
|
||||
// Status = order.OrderStatus,
|
||||
// };
|
||||
// return Ok(response);
|
||||
// }
|
||||
// }
|
||||
43
BrokerApiServer/Controllers/PlanetController.cs
Normal file
43
BrokerApiServer/Controllers/PlanetController.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using BrokerCore.ApiModels;
|
||||
using BrokerCore.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace BrokerApiServer.Controllers;
|
||||
|
||||
using BrokerCore.Common;
|
||||
|
||||
[Route("api/v1/planet")]
|
||||
[ApiController, SwaggerTag("플래닛의 인증 처리")]
|
||||
// 플래닛 인증 컨트롤러
|
||||
public class PlanetController : ControllerBase
|
||||
{
|
||||
private readonly PlanetService m_planet_service;
|
||||
|
||||
public PlanetController(PlanetService planetService)
|
||||
{
|
||||
m_planet_service = planetService;
|
||||
}
|
||||
|
||||
[HttpPost("auth")]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PlanetAuthResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
[SwaggerOperation(Summary = "플래닛 서비스 인증")]
|
||||
public async Task<IActionResult> auth(
|
||||
[FromBody, SwaggerRequestBody(nameof(PlanetAuthRequest))]
|
||||
PlanetAuthRequest request)
|
||||
{
|
||||
Guard.Against.isNull(request, ServerErrorCode.InvalidRequest, ()=>"invalid request");
|
||||
Guard.Against.isNullOrEmptyOrWhiteSpace(request.PlanetId, ServerErrorCode.InvalidRequest,
|
||||
()=>"planet id is required");
|
||||
Guard.Against.isNullOrEmptyOrWhiteSpace(request.PlanetSecretKey, ServerErrorCode.InvalidRequest,
|
||||
()=>"planet access key is required");
|
||||
|
||||
var access_token = await m_planet_service.auth(request.PlanetId, request.PlanetSecretKey);
|
||||
Guard.Against.isNull(access_token, ServerErrorCode.InternalServerError, ()=>"access_token create failed");
|
||||
return Ok(new PlanetAuthResponse { AccessToken = access_token });
|
||||
}
|
||||
}
|
||||
179
BrokerApiServer/Controllers/PlanetUserController.cs
Normal file
179
BrokerApiServer/Controllers/PlanetUserController.cs
Normal file
@@ -0,0 +1,179 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace BrokerApiServer.Controllers;
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
using BrokerCore.ApiModels;
|
||||
using BrokerCore.Common;
|
||||
using BrokerCore.DbEntity;
|
||||
using BrokerCore.Services;
|
||||
|
||||
using Common;
|
||||
|
||||
[Route("api/v1/planet/user")]
|
||||
[ApiController, SwaggerTag("**플래닛 유저의 로그인 및 교환 처리**<br> - /api/v1/planet/auth를 통해 accessToken을 발급받은 후 사용 <br> - Bearer 형식 Hearder로 인증")]
|
||||
public class PlanetUserController : PlanetAuthControllerBase
|
||||
{
|
||||
private readonly PlanetItemExchangeService m_exchange_service;
|
||||
private readonly UserAuthService m_user_auth_service;
|
||||
|
||||
public PlanetUserController(
|
||||
PlanetItemExchangeService exchangeService, UserAuthService userAuthService)
|
||||
{
|
||||
m_exchange_service = exchangeService;
|
||||
m_user_auth_service = userAuthService;
|
||||
}
|
||||
|
||||
[HttpPost, Route("login"), RequirePlanetAuth]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType(typeof(LoginResponse), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ApiErrorResponse), StatusCodes.Status400BadRequest)]
|
||||
[SwaggerOperation(Summary = "웹 포털 런처 토큰으로 칼리버스 유저 인증 처리 [Bearer 인증 필요]",
|
||||
Description = "플래닛의 클라이언트 구동 시 항상 유저 인증 후 실행해야 함")]
|
||||
public async Task<IActionResult> login([FromBody] LoginRequest request)
|
||||
{
|
||||
Guard.Against.isNull(request, ServerErrorCode.InvalidRequest, ()=>"Request is empty");
|
||||
Guard.Against.isNullOrEmptyOrWhiteSpace(request.WebPortalToken, ServerErrorCode.InvalidRequest,
|
||||
()=>"WebPortalToken does not exist");
|
||||
|
||||
var result = await m_user_auth_service.authByWebPortalToken(request.WebPortalToken, this.PlanetId);
|
||||
Guard.Against.resultFail(result);
|
||||
return Ok(new LoginResponse
|
||||
{
|
||||
UserGuid = m_user_auth_service.UserGuid, Nickname = m_user_auth_service.Nickname,
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("currency"), RequirePlanetAuth]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CurrencyBalanceResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
[SwaggerOperation(Summary = "칼리버스 측 재화 현재 수량 조회 [Bearer 인증 필요]")]
|
||||
public async Task<IActionResult> getCurrencyBalance(CurrencyBalanceRequest request)
|
||||
{
|
||||
var sso_account_id = request.SsoAccountId ?? string.Empty;
|
||||
var user_guid = request.UserGuid ?? string.Empty;
|
||||
await m_exchange_service.validateAndGetUser(sso_account_id, user_guid, this.PlanetId);
|
||||
var current_sapphire_amount = await m_exchange_service.getCurrencyAmount(request.CaliverseCurrencyType);
|
||||
return Ok(new CurrencyBalanceResponse { CaliverseCurrencyType = request.CaliverseCurrencyType, Amount = current_sapphire_amount });
|
||||
}
|
||||
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost("sapphire"), RequirePlanetAuth]
|
||||
// [Produces("application/json")]
|
||||
// [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CurrencyBalanceResponse))]
|
||||
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// [SwaggerOperation(Summary = "!! 삭제 예정 => 칼리버스 측 재화 현재 수량 조회로 대체 [Bearer 인증 필요]")]
|
||||
// public async Task<IActionResult> getSapphireBalance(CurrencyBalanceRequest request)
|
||||
// {
|
||||
// var sso_account_id = string.Empty;
|
||||
// await m_exchange_service.validateAndGetUser(sso_account_id, request.UserGuid, this.PlanetId);
|
||||
//
|
||||
// var current_sapphire_amount = await m_exchange_service.getCurrentSapphire();
|
||||
// return Ok(new CurrencyBalanceResponse { Amount = current_sapphire_amount });
|
||||
// }
|
||||
|
||||
[HttpPost("exchange/order/list"), RequirePlanetAuth]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PlanetItemExchangeOrderListResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
[SwaggerOperation(Summary = "교환 주문 목록 조회 [Bearer 인증 필요]")]
|
||||
public async Task<IActionResult> getOrders(
|
||||
[SwaggerRequestBody] PlanetItemExchangeOrderListRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var planet_id = string.IsNullOrEmpty(request.PlanetId) ? this.PlanetId : request.PlanetId;
|
||||
var user_guid = request.UserGuid;
|
||||
var account_id = request.SsoAccountId;
|
||||
await m_exchange_service.validateAndGetUser(account_id, user_guid, this.PlanetId);
|
||||
user_guid = m_exchange_service.PlanetUser.UserGuid;
|
||||
account_id = m_exchange_service.PlanetUser.AccountId;
|
||||
|
||||
ExchangeOrderStatus? order_status = request switch
|
||||
{
|
||||
{ Option: FindOption.Completed } => ExchangeOrderStatus.Completed,
|
||||
{ Option: FindOption.Pending } => ExchangeOrderStatus.Pending,
|
||||
_ => null // 전체 조회
|
||||
};
|
||||
var season_id = request.SeasonId;
|
||||
var request_exchange_meta_id = request.ExchangeMetaId;
|
||||
var page_index = request.PageIndex <= 0 ? 1 : request.PageIndex;
|
||||
var page_size = request.PageSize <= 0 ? 20 : request.PageSize;
|
||||
var (orders, total_count) =
|
||||
await m_exchange_service.findOrderList(planet_id, request_exchange_meta_id, season_id, user_guid, order_status, page_index,
|
||||
page_size, "desc", cancellationToken);
|
||||
|
||||
var order_dtos = orders.Select(x => new PlanetItemExchangeOrderDto
|
||||
{
|
||||
OrderId = x.OrderId,
|
||||
OrderStatus = x.OrderStatus,
|
||||
SeasonId = x.SeasonId,
|
||||
ExchangeMetaId = x.ExchangeMetaId,
|
||||
ExchangeMetaAmount = x.ExchangeMetaAmount,
|
||||
AccountId = x.AccountId,
|
||||
UserGuid = x.UserGuid,
|
||||
PlanetId = x.PlanetId,
|
||||
CaliverseItemType = x.CaliverseItemType,
|
||||
CaliverseItemId = x.CaliverseItemId,
|
||||
CaliverseItemDeltaAmount = x.CaliverseItemDeltaAmount,
|
||||
PlanetItemType = x.PlanetItemType,
|
||||
PlanetItemId = x.PlanetItemId,
|
||||
PlanetItemDeltaAmount = x.PlanetItemDeltaAmount,
|
||||
CreatedAt = x.CreatedAt,
|
||||
CompletedAt = x.CompletedAt,
|
||||
});
|
||||
return Ok(new PlanetItemExchangeOrderListResponse { Orders = order_dtos, TotalCount = total_count });
|
||||
}
|
||||
|
||||
[HttpPost("exchange/order/create"), RequirePlanetAuth]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PlanetItemExchangeResponse))]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse)), Description("에러 발생 시 처리")]
|
||||
[Produces("application/json")]
|
||||
[SwaggerOperation(Summary = "교환 주문 체결 요청 [Bearer 인증 필요]")]
|
||||
public async Task<IActionResult> createOrder(
|
||||
PlanetItemExchangeRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var sso_account_id = string.Empty;
|
||||
var user_guid = request.UserGuid;
|
||||
var season_id = request.SeasonId;
|
||||
await m_exchange_service.validateAndGetUser(sso_account_id, user_guid, this.PlanetId);
|
||||
// 메타버스 클라이언트에서 정상적으로
|
||||
Guard.Against.isTrue(m_exchange_service.isUserLoggedIn(),
|
||||
ServerErrorCode.MetaverseClientOnConnected,
|
||||
()=>"메타버스에 접속 중인 상태. 메타버스에서 정상적으로 로그아웃 한 후에 다시 시도 바람.");
|
||||
|
||||
var (result, order) =
|
||||
await m_exchange_service.createOrder(this.PlanetId, season_id, this.PlanetServerType, request.ExchangeMetaId,
|
||||
request.ExchangeMetaAmount, cancellationToken);
|
||||
Guard.Against.resultFail(result, ServerErrorCode.InternalServerError, ()=>result.ResultString);
|
||||
|
||||
var response = new PlanetItemExchangeResponse { ExchangeOrder = order.toDto(), };
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
[HttpPost("exchange/order/complete"), RequirePlanetAuth]
|
||||
[Produces("application/json")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PlanetItemExchangeResponse))]
|
||||
[SwaggerResponse(StatusCodes.Status400BadRequest, "교환 주문 완료 실패<br>실패 사유를 확인하세요.",
|
||||
typeof(ApiErrorResponse))]
|
||||
[SwaggerOperation(Summary = "교환 주문 완료 요청 [Bearer 인증 필요]")]
|
||||
public async Task<IActionResult> completeOrder(
|
||||
PlanetItemExchangeCompleteRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var sso_account_id = string.Empty;
|
||||
await m_exchange_service.validateAndGetUser(sso_account_id, request.UserGuid, this.PlanetId);
|
||||
// 메타버스 클라이언트에서 정상적으로
|
||||
Guard.Against.isTrue(m_exchange_service.isUserLoggedIn(),
|
||||
ServerErrorCode.MetaverseClientOnConnected,
|
||||
()=>"메타버스에 접속 중인 상태. 메타버스에서 정상적으로 로그아웃 한 후에 다시 시도 바람.");
|
||||
|
||||
var order = await m_exchange_service.completeOrder(request.ExchangeOrderId, cancellationToken);
|
||||
var response = new PlanetItemExchangeResponse { ExchangeOrder = order.toDto() };
|
||||
return Ok(response);
|
||||
}
|
||||
}
|
||||
93
BrokerApiServer/Controllers/UserController.cs
Normal file
93
BrokerApiServer/Controllers/UserController.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// using Asp.Versioning;
|
||||
//
|
||||
// using BrokerCore.ApiModels;
|
||||
// using BrokerCore.Common;
|
||||
// using BrokerCore.DbEntity;
|
||||
// using BrokerCore.Services;
|
||||
//
|
||||
// using Microsoft.AspNetCore.Mvc;
|
||||
//
|
||||
// using ServerCommon;
|
||||
//
|
||||
// using Swashbuckle.AspNetCore.Annotations;
|
||||
//
|
||||
// namespace BrokerApiServer.Controllers;
|
||||
//
|
||||
// [ApiVersion("1.0")]
|
||||
// [Route("api/v1/user")]
|
||||
// [ApiController, SwaggerTag("**PlanetUser 항목으로 이전 후 삭제 예정** (3월 말 예정)")]
|
||||
// // 특별한 인증 없이 런처 토큰만으로도 사용 가능한 컨트롤러
|
||||
// public class UserController : ControllerBase
|
||||
// {
|
||||
// private readonly SapphireExchangeService m_exchange_service;
|
||||
// private readonly IServerLogic m_server_logic;
|
||||
//
|
||||
// public UserController(
|
||||
// IServerLogic serverLogic,
|
||||
// SapphireExchangeService exchangeService)
|
||||
// {
|
||||
// m_server_logic = serverLogic;
|
||||
// m_exchange_service = exchangeService;
|
||||
// }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost("balance/sapphire"), RequireUserJwtAuth]
|
||||
// [Produces("application/json")]
|
||||
// [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserSapphireResponse))]
|
||||
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// [SwaggerOperation(Summary = "유저 사파이어 현재 수량 조회 (유저 sso jwt bearer header 필요)",
|
||||
// Description = "웹 런처에서 발급한 토큰을 header의 authorization에 bearer 형식으로 넣어주세요.")]
|
||||
// public async Task<IActionResult> getSapphireBalance(UserSapphireRequest _)
|
||||
// {
|
||||
// var dynamo_db_client = m_server_logic.getDynamoDbClient();
|
||||
// var user_guid = this.HttpContext.Items["user_guid"] as string ?? string.Empty;
|
||||
// CurrencyControlHelper.setDbConnector(dynamo_db_client);
|
||||
// var (result, current_sapphire_amount_double) =
|
||||
// await CurrencyControlHelper.getMoneyByUserGuid(user_guid, CurrencyType.Sapphire);
|
||||
// Guard.Against.resultFail(result);
|
||||
//
|
||||
// var current_sapphire_amount = Convert.ToInt64(current_sapphire_amount_double);
|
||||
// return Ok(new UserSapphireResponse { SapphireAmount = current_sapphire_amount });
|
||||
// }
|
||||
//
|
||||
// [SwaggerIgnore]
|
||||
// [HttpPost("exchange/order/list"), RequireUserJwtAuth]
|
||||
// [Produces("application/json")]
|
||||
// [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(UserExchangeOrderListResponse))]
|
||||
// [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ApiErrorResponse))]
|
||||
// [SwaggerOperation(Summary = "유저 사파이어 교환 주문 목록 조회 (유저 sso jwt bearer header 필요)",
|
||||
// Description = "웹 런처에서 발급한 토큰을 header의 authorization에 bearer 형식으로 넣어주세요.\n 이기몹의 PlanetId는 igm26_iggymob 입니다.")]
|
||||
// public async Task<IActionResult> getOrdersForUser(
|
||||
// [SwaggerRequestBody] UserExchangeOrderListRequest request,
|
||||
// CancellationToken cancellationToken)
|
||||
// {
|
||||
// var planet_id = request.PlanetId;
|
||||
// var user_guid = this.HttpContext.Items["user_guid"]?.ToString() ?? string.Empty;
|
||||
// Guard.Against.isNullOrEmptyOrWhiteSpace(user_guid,
|
||||
// ServerErrorCode.AccountNotFound, "해당 유저를 찾을 수 없음");
|
||||
// await m_exchange_service.authUser(user_guid, string.Empty);
|
||||
//
|
||||
// ExchangeOrderStatus? order_status = request switch
|
||||
// {
|
||||
// { Option: FindOption.Completed } => ExchangeOrderStatus.Completed,
|
||||
// { Option: FindOption.Pending } => ExchangeOrderStatus.Pending,
|
||||
// _ => null // 전체 조회
|
||||
// };
|
||||
// var orders =
|
||||
// await m_exchange_service.findOrderList(planet_id, user_guid, order_status,
|
||||
// request.PageIndex, request.PageSize, request.SortOrder,
|
||||
// cancellationToken);
|
||||
// var mapped_orders = orders.Select(x => new ExchangeOrder
|
||||
// {
|
||||
// OrderId = x.OrderId,
|
||||
// SapphireAmount = x.SapphireReducedDelta,
|
||||
// SapphireReduceAmount = x.SapphireReducedDelta,
|
||||
// EmeraldAmount = x.PlanetMoneyIncDelta,
|
||||
// CreatedAt = x.CreatedAt,
|
||||
// CompletedAt = x.CompletedAt,
|
||||
// Status = x.OrderStatus
|
||||
// });
|
||||
// return Ok(new UserExchangeOrderListResponse { Orders = mapped_orders });
|
||||
// }
|
||||
// }
|
||||
8
BrokerApiServer/Directory.Build.props
Normal file
8
BrokerApiServer/Directory.Build.props
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseIntermediateOutputPath>..\..\obj\AnyCPU\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
|
||||
<BaseOutputPath>..\..\bin\</BaseOutputPath>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
285
BrokerApiServer/Extensions/AppBuilderExtensions.cs
Normal file
285
BrokerApiServer/Extensions/AppBuilderExtensions.cs
Normal file
@@ -0,0 +1,285 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Text;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
using BrokerCore;
|
||||
using BrokerCore.Repository;
|
||||
using BrokerCore.Repository.Context;
|
||||
using BrokerCore.Services;
|
||||
using BrokerCore.Common;
|
||||
|
||||
namespace BrokerApiServer.Extensions;
|
||||
|
||||
using BrokerCore.Meta;
|
||||
|
||||
using Common;
|
||||
|
||||
using NLog.Config;
|
||||
|
||||
public static class AppBuilderExtensions
|
||||
{
|
||||
public static void initGlobalNlog()
|
||||
{
|
||||
// nlog 설정
|
||||
var nlog_config_path = "./Config/nlog.config";
|
||||
var full_path = Path.GetFullPath(nlog_config_path);
|
||||
if (!File.Exists(full_path))
|
||||
{
|
||||
full_path = Path.GetFullPath(nlog_config_path, AppContext.BaseDirectory);
|
||||
if (!File.Exists(full_path))
|
||||
{
|
||||
throw new ApplicationException($"nlog.config 파일을 찾을 수 없음 => {full_path}");
|
||||
}
|
||||
}
|
||||
|
||||
Log.NLogFileName = full_path;
|
||||
}
|
||||
|
||||
public static ServerConfigMetaverseBroker initBrokerServerConfig()
|
||||
{
|
||||
// 서버 설정
|
||||
var server_config = new ServerConfigMetaverseBroker();
|
||||
var server_config_path = "./Config/ServerConfig.json";
|
||||
var full_path = Path.GetFullPath(server_config_path);
|
||||
if (!File.Exists(full_path))
|
||||
{
|
||||
full_path = Path.GetFullPath(server_config_path, AppContext.BaseDirectory);
|
||||
if (!File.Exists(full_path))
|
||||
{
|
||||
throw new ApplicationException("ServerConfig.json 파일을 찾을 수 없음");
|
||||
}
|
||||
}
|
||||
server_config.setConfigFilePath(full_path);
|
||||
var result = server_config.tryLoadConfig().GetAwaiter().GetResult();
|
||||
Guard.Against.resultFail(result);
|
||||
return server_config;
|
||||
}
|
||||
|
||||
public static void addBrokerServerLogic(this IServiceCollection services,
|
||||
ServerConfigMetaverseBroker serverConfig)
|
||||
{
|
||||
var broker_logic = new BrokerServerLogic(serverConfig);
|
||||
var result = broker_logic.onInit().GetAwaiter().GetResult();
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"BrokerServerLogic Init Failed => {result}");
|
||||
throw new ApplicationException($"BrokerServerLogic Init Failed => {result}");
|
||||
}
|
||||
ServerLogicApp.setServerLogicApp(broker_logic);
|
||||
services.AddSingleton<IServerLogic>(broker_logic);
|
||||
}
|
||||
|
||||
public static void addCoreServices(this IServiceCollection services,
|
||||
ServerConfigMetaverseBroker serverConfig)
|
||||
{
|
||||
services.AddSingleton(serverConfig);
|
||||
|
||||
var broker_logic = new BrokerServerLogic(serverConfig);
|
||||
var result = broker_logic.onInit().GetAwaiter().GetResult();
|
||||
services.AddSingleton<IServerLogic>(broker_logic);
|
||||
|
||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = false,
|
||||
ValidateAudience = false,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(serverConfig.MetaverseBroker?.JwtSecretKey ?? String.Empty))
|
||||
};
|
||||
});
|
||||
|
||||
services.AddScoped<UserAuthService>();
|
||||
|
||||
services.addExchangeServices();
|
||||
|
||||
// 메타데이터 관련 서비스 등록
|
||||
services.AddSingleton<BrokerApiMetaLoader>();
|
||||
services.AddScoped<BrokerMetaTableRef>( provider =>
|
||||
{
|
||||
var meta_loader = provider.GetRequiredService<BrokerApiMetaLoader>();
|
||||
return new BrokerMetaTableRef(meta_loader.getMetaTable());
|
||||
});
|
||||
services.AddHostedService<MetaDataReloadScheduler>();
|
||||
|
||||
var jwt_option = new JwtOption
|
||||
{
|
||||
Secret = serverConfig.MetaverseBroker?.JwtSecretKey ?? String.Empty,
|
||||
TokenValidityInMinutes = serverConfig.MetaverseBroker?.ExpireMinutes ?? 1
|
||||
};
|
||||
services.AddSingleton(jwt_option);
|
||||
|
||||
services.AddScoped<JwtGenerator>(provider =>
|
||||
{
|
||||
return new JwtGenerator(jwt_option);
|
||||
});
|
||||
services.AddScoped<JwtParser>(provider =>
|
||||
{
|
||||
return new JwtParser(jwt_option);
|
||||
});
|
||||
|
||||
services.AddScoped<PlanetService>();
|
||||
|
||||
// 미들웨어 설정
|
||||
services.AddScoped<ResultLoggingMiddleware>();
|
||||
}
|
||||
|
||||
public static void addInfraServices(this IServiceCollection services, ServerConfigMetaverseBroker serverConfig)
|
||||
{
|
||||
// 코어 리파지토리 서비스 설정
|
||||
services.AddScoped<SsoAccountRepo>();
|
||||
services.AddScoped<PlanetInfoRepo>();
|
||||
services.AddScoped<PlanetItemExchangeOrderRepo>();
|
||||
services.AddScoped<PlanetItemExchangeOrderAmountTotalLimitRepo>();
|
||||
services.AddScoped<PlanetItemExchangeOrderAmountUserLimitRepo>();
|
||||
|
||||
services.AddDbContext<SsoAccountDbContext>(options =>
|
||||
{
|
||||
var connection_string = serverConfig.SsoAccountDb;
|
||||
|
||||
options.UseMySql(connection_string, ServerVersion.AutoDetect(connection_string), mySqlOptions =>
|
||||
{
|
||||
mySqlOptions.EnableRetryOnFailure(
|
||||
maxRetryCount: 10,
|
||||
maxRetryDelay: TimeSpan.FromSeconds(30),
|
||||
errorNumbersToAdd: null
|
||||
);
|
||||
mySqlOptions.CommandTimeout(60);
|
||||
mySqlOptions.MaxBatchSize(20);
|
||||
});
|
||||
});
|
||||
|
||||
services.AddDbContext<MetaverseBrokerDbContext>(options =>
|
||||
{
|
||||
var connection_string = serverConfig.MetaverseBroker?.MetaverseBrokerDb;
|
||||
|
||||
options.UseMySql(connection_string, ServerVersion.AutoDetect(connection_string), my_sql_options =>
|
||||
{
|
||||
my_sql_options.EnableRetryOnFailure(
|
||||
maxRetryCount: 10,
|
||||
maxRetryDelay: TimeSpan.FromSeconds(30),
|
||||
errorNumbersToAdd: null
|
||||
);
|
||||
my_sql_options.CommandTimeout(60);
|
||||
my_sql_options.MaxBatchSize(20);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// todo: isLocal 삭제 예정
|
||||
public static void addAppServices(this WebApplicationBuilder builder)
|
||||
{
|
||||
initGlobalNlog();
|
||||
var server_config = initBrokerServerConfig();
|
||||
builder.Services.addBrokerServerLogic(server_config);
|
||||
builder.Services.addCoreServices(server_config);
|
||||
builder.Services.addInfraServices(server_config);
|
||||
}
|
||||
|
||||
public static void brokerServerLogicInit(this IApplicationBuilder app)
|
||||
{
|
||||
var server_logic = app.ApplicationServices.GetRequiredService<IServerLogic>() as BrokerServerLogic;
|
||||
NullReferenceCheckHelper.throwIfNull(server_logic, () => $"BrokerServerLogic is null");
|
||||
server_logic.onInit().Wait();
|
||||
}
|
||||
|
||||
public static void metadataMangerInit(this IApplicationBuilder app, string? dataPath = null)
|
||||
{
|
||||
var meta_loader = app.ApplicationServices.GetRequiredService<BrokerApiMetaLoader>();
|
||||
var result = meta_loader.load(dataPath);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"MetaDataManager Init Failed => {result}");
|
||||
throw new ApplicationException($"MetaDataManager Init Failed => {result}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateRepoConnections(this IApplicationBuilder app)
|
||||
{
|
||||
var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
|
||||
// db 접속 유무 검사
|
||||
using var scope = app.ApplicationServices.CreateScope();
|
||||
var services = scope.ServiceProvider;
|
||||
validateSsoAccountDb().Wait();
|
||||
validateMetaverseBrokerDb().Wait();
|
||||
migrateMetaverseBrokerDbForDevelopment().Wait();
|
||||
return;
|
||||
|
||||
async Task validateSsoAccountDb()
|
||||
{
|
||||
var context = services.GetRequiredService<SsoAccountDbContext>();
|
||||
try
|
||||
{
|
||||
if (await context.Database.CanConnectAsync())
|
||||
{
|
||||
Log.getLogger().info($"Sso Account DB Connection OK => {context.Database.GetConnectionString()}");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.getLogger().error($"Sso Account DB Connection Failed => {context.Database.GetConnectionString()}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.getLogger()
|
||||
.error(
|
||||
$"Sso Account DB Connection Failed => {ex.Message}, {context.Database.GetConnectionString()}");
|
||||
}
|
||||
|
||||
throw new ApplicationException($"Failed to connect Sso Account Db !!!");
|
||||
}
|
||||
|
||||
async Task validateMetaverseBrokerDb()
|
||||
{
|
||||
var context = services.GetRequiredService<MetaverseBrokerDbContext>();
|
||||
try
|
||||
{
|
||||
if (await context.Database.CanConnectAsync())
|
||||
{
|
||||
Log.getLogger()
|
||||
.info($"Metaverse-Broker DB Connection OK => {context.Database.GetConnectionString()}");
|
||||
var pending_migrations = await context.Database.GetPendingMigrationsAsync();
|
||||
var migrations = pending_migrations as string[] ?? pending_migrations.ToArray();
|
||||
if (migrations.Any())
|
||||
{
|
||||
Log.getLogger().error($"{context.Database.ToString()} 마이그레션이 필요함 !!!");
|
||||
migrations.Select( x => x.ToString()).ToList().ForEach(x => Log.getLogger().warn(x));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.getLogger()
|
||||
.error($"Metaverse-Broker DB 접속 예외 발생 => {ex.Message}, {context.Database.GetConnectionString()}");
|
||||
}
|
||||
|
||||
throw new ApplicationException($"Failed to connect Broker Db !!!");
|
||||
}
|
||||
|
||||
async Task migrateMetaverseBrokerDbForDevelopment()
|
||||
{
|
||||
// if (!env.IsDevelopment())
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
var context = services.GetRequiredService<MetaverseBrokerDbContext>();
|
||||
try
|
||||
{
|
||||
await context.Database.MigrateAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.getLogger().error($"Metaverse-Broker DB Migrate 실패 => {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ControlCenter.NamedPipe;
|
||||
using ControlCenter.NamedPipeHost.Manager;
|
||||
using ServerControlCenter;
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace BrokerApiServer.NamedPipePacketHandler;
|
||||
|
||||
public class ForceStopServerMessageReceiver : NamedPipeReceiver<A2S_REQ_FORCE_STOP_SERVER>
|
||||
{
|
||||
private readonly ServerInfoManager m_info_manager;
|
||||
|
||||
public ForceStopServerMessageReceiver(ServerInfoManager infoManager)
|
||||
{
|
||||
m_info_manager = infoManager;
|
||||
}
|
||||
|
||||
public override async Task Handle(A2S_REQ_FORCE_STOP_SERVER message, string message_id)
|
||||
{
|
||||
Log.getLogger().debug($"{nameof(ForceStopServerMessageReceiver)}: Receive - message_id[{message_id}] / message[{message}]");
|
||||
|
||||
m_info_manager.setServerStatus(ServerStatus.Stop);
|
||||
|
||||
// 정보 전달 대기
|
||||
await Task.Delay(1_000);
|
||||
|
||||
// process 종료
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using ControlCenter.NamedPipeHost.Manager;
|
||||
using ControlCenter.NamedPipeHost.NamedPipe;
|
||||
using ServerControlCenter;
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
namespace BrokerApiServer.NamedPipePacketHandler;
|
||||
|
||||
public class StopServerMessageReceiver : NamedPipeReceiver<A2S_REQ_STOP_SERVER>
|
||||
{
|
||||
private readonly ServerInfoManager m_info_manager;
|
||||
|
||||
public StopServerMessageReceiver(ServerInfoManager infoManager)
|
||||
{
|
||||
m_info_manager = infoManager;
|
||||
}
|
||||
|
||||
public override async Task Handle(A2S_REQ_STOP_SERVER message, string message_id)
|
||||
{
|
||||
Log.getLogger().debug($"{nameof(StopServerMessageReceiver)}: Receive - message_id[{message_id}] / message[{message}]");
|
||||
|
||||
m_info_manager.setServerStatus(ServerStatus.Stop);
|
||||
|
||||
// 정보 전달 대기
|
||||
await Task.Delay(1_000);
|
||||
|
||||
// process 종료
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
77
BrokerApiServer/Program.cs
Normal file
77
BrokerApiServer/Program.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System.Reflection;
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
using BrokerApiServer.Common;
|
||||
using BrokerApiServer.Extensions;
|
||||
using CaliGameApi.Middlewares;
|
||||
using CommandLine;
|
||||
using ControlCenter.NamedPipeHost.Extensions;
|
||||
|
||||
//=============================================================================
|
||||
// 인자 설정
|
||||
//=============================================================================
|
||||
var port = 12000;
|
||||
var use_swagger = false;
|
||||
var use_named_pipe = false;
|
||||
var parsed_arguments = Parser.Default.ParseArguments<CommandLineOption>(args);
|
||||
if (parsed_arguments is Parsed<CommandLineOption> parsed)
|
||||
{
|
||||
port = parsed.Value.Port;
|
||||
use_swagger = parsed.Value.UseSwagger ? true : false;
|
||||
use_named_pipe = parsed.Value.UseNamedPipe ? true : false;
|
||||
}
|
||||
|
||||
var cmd_options = new string[] { "--urls", $"http://*:{port}" };
|
||||
|
||||
var builder = WebApplication.CreateBuilder(cmd_options);
|
||||
builder.addAppServices();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddControllers(options => { options.Filters.Add(new ResultExceptionFilter()); });
|
||||
builder.Services.AddHealthChecks();
|
||||
builder.Services.AddSwaggerGen(SwaggerSettingHelper.setSwaggerGen);
|
||||
|
||||
var assemblies = new List<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
|
||||
if (use_named_pipe)
|
||||
{
|
||||
builder.Services.AddNamedPipelineClientManager(assemblies, ServerControlCenter.ServerType.BrokerApi,
|
||||
ServiceCategory.Caliverse.ToString(), NetworkHelper.getEthernetLocalIPv4(), port);
|
||||
}
|
||||
|
||||
var app = builder.Build();
|
||||
app.UseCors("Everything");
|
||||
app.UseHttpsRedirection();
|
||||
app.UseMiddleware<ResultLoggingMiddleware>();
|
||||
app.UseAuthorization();
|
||||
app.UseRouting();
|
||||
app.MapControllers();
|
||||
if (use_swagger)
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.MapHealthChecks("/healthcheck");
|
||||
|
||||
app.validateRepoConnections();
|
||||
app.brokerServerLogicInit();
|
||||
|
||||
// todo: 스키마 변경 시 자동으로 앱에서 마이그레이션 하지 않고, dotnet ef 툴을 사용할 것
|
||||
// app.metadataMangerInit();
|
||||
|
||||
app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStarted.Register(() =>
|
||||
{
|
||||
Log.getLogger().info($"Env : {app.Environment.EnvironmentName}");
|
||||
Log.getLogger().info($"BrokerApiServer started {app.Urls}");
|
||||
});
|
||||
app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStopped.Register(Log.shutdown);
|
||||
|
||||
if (use_named_pipe)
|
||||
{
|
||||
app.UseNamedPipelineClientManager();
|
||||
}
|
||||
|
||||
app.Run();
|
||||
15
BrokerApiServer/Properties/launchSettings.json
Normal file
15
BrokerApiServer/Properties/launchSettings.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "-p 12000 -s",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:12000"
|
||||
}
|
||||
}
|
||||
}
|
||||
1641
BrokerApiServer/obj/BrokerApiServer.csproj.nuget.dgspec.json
Normal file
1641
BrokerApiServer/obj/BrokerApiServer.csproj.nuget.dgspec.json
Normal file
File diff suppressed because it is too large
Load Diff
26
BrokerApiServer/obj/BrokerApiServer.csproj.nuget.g.props
Normal file
26
BrokerApiServer/obj/BrokerApiServer.csproj.nuget.g.props
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\user\.nuget\packages\</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.10.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\user\.nuget\packages\" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.props" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.2\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.2\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<PkgAWSSDK_Core Condition=" '$(PkgAWSSDK_Core)' == '' ">C:\Users\user\.nuget\packages\awssdk.core\3.7.400</PkgAWSSDK_Core>
|
||||
<PkgAWSSDK_S3 Condition=" '$(PkgAWSSDK_S3)' == '' ">C:\Users\user\.nuget\packages\awssdk.s3\3.7.400</PkgAWSSDK_S3>
|
||||
<PkgAWSSDK_OpenSearchService Condition=" '$(PkgAWSSDK_OpenSearchService)' == '' ">C:\Users\user\.nuget\packages\awssdk.opensearchservice\3.7.400</PkgAWSSDK_OpenSearchService>
|
||||
<PkgAWSSDK_DynamoDBv2 Condition=" '$(PkgAWSSDK_DynamoDBv2)' == '' ">C:\Users\user\.nuget\packages\awssdk.dynamodbv2\3.7.400</PkgAWSSDK_DynamoDBv2>
|
||||
<PkgAWSSDK_CloudWatchLogs Condition=" '$(PkgAWSSDK_CloudWatchLogs)' == '' ">C:\Users\user\.nuget\packages\awssdk.cloudwatchlogs\3.7.305.15</PkgAWSSDK_CloudWatchLogs>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
10
BrokerApiServer/obj/BrokerApiServer.csproj.nuget.g.targets
Normal file
10
BrokerApiServer/obj/BrokerApiServer.csproj.nuget.g.targets
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("BrokerApiServer")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("BrokerApiServer")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("BrokerApiServer")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// MSBuild WriteCodeFragment 클래스에서 생성되었습니다.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
f42f565cd904b4b097fb70fdee38c8e886209a12f509c9e7c43b23319c324d43
|
||||
@@ -0,0 +1,19 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net8.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb = true
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = BrokerApiServer
|
||||
build_property.RootNamespace = BrokerApiServer
|
||||
build_property.ProjectDir = D:\03.SVN\03.caliverse\Server\CaliServer\BrokerApiServer\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.RazorLangVersion = 8.0
|
||||
build_property.SupportLocalizedComponentNames =
|
||||
build_property.GenerateRazorMetadataSourceChecksumAttributes =
|
||||
build_property.MSBuildProjectDirectory = D:\03.SVN\03.caliverse\Server\CaliServer\BrokerApiServer
|
||||
build_property._RazorSourceGeneratorDebug =
|
||||
@@ -0,0 +1,17 @@
|
||||
// <auto-generated/>
|
||||
global using global::Microsoft.AspNetCore.Builder;
|
||||
global using global::Microsoft.AspNetCore.Hosting;
|
||||
global using global::Microsoft.AspNetCore.Http;
|
||||
global using global::Microsoft.AspNetCore.Routing;
|
||||
global using global::Microsoft.Extensions.Configuration;
|
||||
global using global::Microsoft.Extensions.DependencyInjection;
|
||||
global using global::Microsoft.Extensions.Hosting;
|
||||
global using global::Microsoft.Extensions.Logging;
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Net.Http.Json;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
BIN
BrokerApiServer/obj/Debug/net8.0/BrokerApiServer.assets.cache
Normal file
BIN
BrokerApiServer/obj/Debug/net8.0/BrokerApiServer.assets.cache
Normal file
Binary file not shown.
Binary file not shown.
4322
BrokerApiServer/obj/project.assets.json
Normal file
4322
BrokerApiServer/obj/project.assets.json
Normal file
File diff suppressed because it is too large
Load Diff
104
BrokerApiServer/obj/project.nuget.cache
Normal file
104
BrokerApiServer/obj/project.nuget.cache
Normal file
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "FdIgw7z7uM0=",
|
||||
"success": true,
|
||||
"projectFilePath": "D:\\03.SVN\\03.caliverse\\Server\\CaliServer\\BrokerApiServer\\BrokerApiServer.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\user\\.nuget\\packages\\asp.versioning.abstractions\\8.1.0\\asp.versioning.abstractions.8.1.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\asp.versioning.http\\8.1.0\\asp.versioning.http.8.1.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\asp.versioning.mvc\\8.1.0\\asp.versioning.mvc.8.1.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\asyncstatemachine\\1.3.2\\asyncstatemachine.1.3.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\aws.logger.core\\3.3.3\\aws.logger.core.3.3.3.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\aws.logger.nlog\\3.3.4\\aws.logger.nlog.3.3.4.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\awssdk.cloudwatchlogs\\3.7.305.15\\awssdk.cloudwatchlogs.3.7.305.15.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\awssdk.core\\3.7.400\\awssdk.core.3.7.400.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\awssdk.dynamodbv2\\3.7.400\\awssdk.dynamodbv2.3.7.400.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\awssdk.opensearchservice\\3.7.400\\awssdk.opensearchservice.3.7.400.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\awssdk.s3\\3.7.400\\awssdk.s3.3.7.400.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\axion.concurrenthashset\\1.0.0\\axion.concurrenthashset.1.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\commandlineparser\\2.9.1\\commandlineparser.2.9.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\dotnet.multimap\\2.2.1\\dotnet.multimap.2.2.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\dumpextensions\\2.0.0\\dumpextensions.2.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\google.protobuf\\3.27.1\\google.protobuf.3.27.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.aspnetcore\\2.63.0\\grpc.aspnetcore.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.aspnetcore.server\\2.63.0\\grpc.aspnetcore.server.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.aspnetcore.server.clientfactory\\2.63.0\\grpc.aspnetcore.server.clientfactory.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.aspnetcore.server.reflection\\2.63.0\\grpc.aspnetcore.server.reflection.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.core.api\\2.63.0\\grpc.core.api.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.net.client\\2.63.0\\grpc.net.client.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.net.clientfactory\\2.63.0\\grpc.net.clientfactory.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.net.common\\2.63.0\\grpc.net.common.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\grpc.reflection\\2.63.0\\grpc.reflection.2.63.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\jwt\\10.1.1\\jwt.10.1.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.entityframeworkcore\\8.0.2\\microsoft.entityframeworkcore.8.0.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\8.0.2\\microsoft.entityframeworkcore.abstractions.8.0.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\8.0.2\\microsoft.entityframeworkcore.analyzers.8.0.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\8.0.2\\microsoft.entityframeworkcore.relational.8.0.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\8.0.0\\microsoft.extensions.caching.abstractions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.caching.memory\\8.0.0\\microsoft.extensions.caching.memory.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.configuration\\8.0.0\\microsoft.extensions.configuration.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\8.0.0\\microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.configuration.binder\\8.0.0\\microsoft.extensions.configuration.binder.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.configuration.fileextensions\\8.0.0\\microsoft.extensions.configuration.fileextensions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.configuration.json\\8.0.0\\microsoft.extensions.configuration.json.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.configuration.usersecrets\\8.0.0\\microsoft.extensions.configuration.usersecrets.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\8.0.0\\microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.1\\microsoft.extensions.dependencyinjection.abstractions.8.0.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.diagnostics\\8.0.0\\microsoft.extensions.diagnostics.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.diagnostics.abstractions\\8.0.0\\microsoft.extensions.diagnostics.abstractions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.fileproviders.abstractions\\8.0.0\\microsoft.extensions.fileproviders.abstractions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.fileproviders.physical\\8.0.0\\microsoft.extensions.fileproviders.physical.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.filesystemglobbing\\8.0.0\\microsoft.extensions.filesystemglobbing.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.http\\8.0.0\\microsoft.extensions.http.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.logging\\8.0.0\\microsoft.extensions.logging.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\8.0.0\\microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.options\\8.0.0\\microsoft.extensions.options.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.options.configurationextensions\\8.0.0\\microsoft.extensions.options.configurationextensions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.extensions.primitives\\8.0.0\\microsoft.extensions.primitives.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.identitymodel.abstractions\\7.6.2\\microsoft.identitymodel.abstractions.7.6.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.identitymodel.jsonwebtokens\\7.6.2\\microsoft.identitymodel.jsonwebtokens.7.6.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.identitymodel.logging\\7.6.2\\microsoft.identitymodel.logging.7.6.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.identitymodel.tokens\\7.6.2\\microsoft.identitymodel.tokens.7.6.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\microsoft.openapi\\1.6.22\\microsoft.openapi.1.6.22.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\mongodb.bson\\2.26.0\\mongodb.bson.2.26.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\mysqlconnector\\2.3.7\\mysqlconnector.2.3.7.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\neosmart.asynclock\\3.2.1\\neosmart.asynclock.3.2.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\newtonsoft.json\\13.0.3\\newtonsoft.json.13.0.3.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.asyncex\\5.1.2\\nito.asyncex.5.1.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.asyncex.context\\5.1.2\\nito.asyncex.context.5.1.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.asyncex.coordination\\5.1.2\\nito.asyncex.coordination.5.1.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.asyncex.interop.waithandles\\5.1.2\\nito.asyncex.interop.waithandles.5.1.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.asyncex.oop\\5.1.2\\nito.asyncex.oop.5.1.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.asyncex.tasks\\5.1.2\\nito.asyncex.tasks.5.1.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.cancellation\\1.1.2\\nito.cancellation.1.1.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.collections.deque\\1.1.1\\nito.collections.deque.1.1.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nito.disposables\\2.2.1\\nito.disposables.2.2.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nlog\\5.3.2\\nlog.5.3.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nlog.extensions.logging\\5.3.11\\nlog.extensions.logging.5.3.11.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\nlog.web.aspnetcore\\5.3.11\\nlog.web.aspnetcore.5.3.11.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\otp.net\\1.4.0\\otp.net.1.4.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\pipelines.sockets.unofficial\\2.2.8\\pipelines.sockets.unofficial.2.2.8.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\pomelo.entityframeworkcore.mysql\\8.0.2\\pomelo.entityframeworkcore.mysql.8.0.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\rabbitmq.client\\6.8.1\\rabbitmq.client.6.8.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\ssh.net\\2024.0.0\\ssh.net.2024.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\stackexchange.redis\\2.8.24\\stackexchange.redis.2.8.24.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\stackexchange.redis.extensions.core\\10.2.0\\stackexchange.redis.extensions.core.10.2.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\stackexchange.redis.extensions.newtonsoft\\10.2.0\\stackexchange.redis.extensions.newtonsoft.10.2.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\stackexchange.redis.multiplexerpool\\2.2.0\\stackexchange.redis.multiplexerpool.2.2.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\swashbuckle.aspnetcore.annotations\\7.2.0\\swashbuckle.aspnetcore.annotations.7.2.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\swashbuckle.aspnetcore.swagger\\7.2.0\\swashbuckle.aspnetcore.swagger.7.2.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\swashbuckle.aspnetcore.swaggergen\\7.2.0\\swashbuckle.aspnetcore.swaggergen.7.2.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\swashbuckle.aspnetcore.swaggerui\\7.2.0\\swashbuckle.aspnetcore.swaggerui.7.2.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.collections.immutable\\1.7.1\\system.collections.immutable.1.7.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.diagnostics.diagnosticsource\\8.0.0\\system.diagnostics.diagnosticsource.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.identitymodel.tokens.jwt\\7.6.2\\system.identitymodel.tokens.jwt.7.6.2.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.io.pipelines\\5.0.1\\system.io.pipelines.5.0.1.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.memory\\4.5.5\\system.memory.4.5.5.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.reactive\\6.0.0\\system.reactive.6.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\5.0.0\\system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.text.encodings.web\\8.0.0\\system.text.encodings.web.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.text.json\\8.0.0\\system.text.json.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\user\\.nuget\\packages\\system.threading.channels\\7.0.0\\system.threading.channels.7.0.0.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
1
BrokerApiServer/obj/project.packagespec.json
Normal file
1
BrokerApiServer/obj/project.packagespec.json
Normal file
File diff suppressed because one or more lines are too long
1
BrokerApiServer/obj/rider.project.model.nuget.info
Normal file
1
BrokerApiServer/obj/rider.project.model.nuget.info
Normal file
@@ -0,0 +1 @@
|
||||
17388052526770821
|
||||
1
BrokerApiServer/obj/rider.project.restore.info
Normal file
1
BrokerApiServer/obj/rider.project.restore.info
Normal file
@@ -0,0 +1 @@
|
||||
17388294830086441
|
||||
Reference in New Issue
Block a user