초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using ServerCore; using ServerBase;
namespace BrokerTest.Helper;
using System.Reflection;
using BrokerApiServer.Common;
using BrokerApiServer.Controllers;
using BrokerApiServer.Extensions;
using CaliGameApi.Middlewares;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public interface IBrokerTestServer
{
HttpClient getTestClient();
TService? getRequiredService<TService>() where TService : class;
}
public interface IBrokerTestServerLocal: IBrokerTestServer
{
TService? getService<TService>(in IServiceScope scope) where TService : class;
}
public class BrokerTestServerFactory
{
public static IBrokerTestServer createServer()
{
return new BrokerTestServer();
}
public static IBrokerTestServer createRemoteServer(string baseUrl)
{
return new BrokerTestRemoteServer(baseUrl);
}
}
public class BrokerTestRemoteServer: IBrokerTestServer
{
private readonly string m_base_url;
public BrokerTestRemoteServer(string baseUrl)
{
m_base_url = baseUrl;
}
public HttpClient getTestClient()
{
return new HttpClient { BaseAddress = new Uri(m_base_url) };
}
public TService? getRequiredService<TService>() where TService : class
{
throw new NotImplementedException();
}
}
public class BrokerTestServer: IBrokerTestServerLocal
{
private readonly WebApplication m_server;
public BrokerTestServer()
{
m_server = runWebApp();
Assert.NotNull(m_server);
}
WebApplication runWebApp()
{
var port = 12000;
var cmd_options = new string[] { "--urls", $"http://localhost:{port}" };
// Arrange
var builder = WebApplication.CreateBuilder(cmd_options);
builder.Logging.AddNLog(new NLogProviderOptions{ ReplaceLoggerFactory = true });
builder.Logging.AddConsole();
builder.addAppServices();
builder.Services.AddHttpContextAccessor();
// builder.Services.AddControllers(options => { options.Filters.Add(new ResultExceptionFilter()); });
var assembly = Assembly.GetAssembly(typeof(PlanetUserController));
Assert.NotNull(assembly);
builder.Services.AddControllers(options => { options.Filters.Add(new ResultExceptionFilter()); })
.AddApplicationPart(assembly); // 이유는 모르겠지만 이게 없으면 테스트에서 404 에러 발생 - 컨트롤러가 없음
builder.Services.AddHealthChecks();
builder.Services.AddEndpointsApiExplorer();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("Everything");
app.UseMiddleware<ResultLoggingMiddleware>();
app.UseAuthorization();
app.MapControllers();
app.MapHealthChecks("/healthcheck");
app.validateRepoConnections();
app.brokerServerLogicInit();
app.metadataMangerInit(TestDefines.MetaDataPath);
app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStarted.Register(() =>
{
// Log.getLogger().info($"Env : {app.Environment.EnvironmentName}");
// Log.getLogger().info($"BrokerApiServer started {port}");
// todo 왜 enpoints가 1개 뿐이지?
Console.WriteLine($"Env : {app.Environment.EnvironmentName}");
});
// app.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStopped.Register(Log.shutdown);
app.RunAsync().ConfigureAwait(false);
return app;
}
public HttpClient getTestClient()
{
var url = m_server.Urls.FirstOrDefault()?.ToString() ?? "http://localhost:12000";
var http_client = new HttpClient();
http_client.BaseAddress = new Uri(url);
return http_client;
}
public TService? getRequiredService<TService>() where TService : class
{
return m_server.Services.GetRequiredService<TService>();
}
public TService? getService<TService>(in IServiceScope scope) where TService : class
{
return scope.ServiceProvider.GetRequiredService<TService>();
}
}

View File

@@ -0,0 +1,19 @@
// namespace BrokerCore.Repository;
//
// using ServerCommon;
//
// public class AccountDocRepo
// {
// private readonly DynamoDbClient m_dynamo_db_client;
//
// public AccountDocRepo(DynamoDbClient dynamoDbClient)
// {
// m_dynamo_db_client = dynamoDbClient;
// }
//
// public async Task<(Result, AccountBaseAttrib?)> findAccountBaseAttrib(string accountId)
// {
// var (result, doc) = await AccountBaseDoc.findUserGuidFromAccountId(m_dynamo_db_client, accountId);
// return (result, doc?.getAttrib<AccountBaseAttrib>());
// }
// }

View File

@@ -0,0 +1,53 @@
// namespace BrokerCore.Repository;
//
// using ServerCommon;
// using ServerCommon.EchoSystem.Models;
//
// using ServerCore; using ServerBase;
//
// public class CaliumEventDocRepo
// {
// private readonly DynamoDbClient m_dynamo_db_client;
//
// public CaliumEventDocRepo(DynamoDbClient dynamoDbClient)
// {
// m_dynamo_db_client = dynamoDbClient;
// }
//
// // public async Task<(Result, CaliumEventAttrib?)> createOne(string userGuid)
// // {
// // var (result_pk, primary_key_object) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumEventDoc>(userGuid);
// // if (result_pk.isFail() || primary_key_object == null)
// // {
// // return (result_pk, null);
// // }
// //
// // var config = m_dynamo_db_client.makeQueryConfigForReadByPKOnly(primary_key_object.PK);
// // var (result, doc) =
// // await m_dynamo_db_client.simpleInsertDocument<CaliumEventDoc>(config);
// // var attrib = doc?.getAttrib<CaliumEventAttrib>();
// // return (result, attrib);
// // }
// public async Task<string> createOne(string userGuid, CaliumEventRequest request, bool isRetry)
// {
// var doc = new CaliumEventDoc(request.m_event_id);
// var attrib = doc.getAttrib<CaliumEventAttrib>();
// NullReferenceCheckHelper.throwIfNull(attrib, () => $"calium event attrib is null !!! - userGuid[{userGuid}]");
//
// attrib.UserGuid = userGuid;
// attrib.EventData.m_server_type = request.m_server_type;
// attrib.EventData.m_event_type = request.m_event_type;
// attrib.EventData.m_sub_type = request.m_sub_type;
// attrib.EventData.m_div_type = request.m_div_type;
// attrib.EventData.m_div_id = request.m_div_id;
// attrib.EventData.m_calium_delta = request.m_calium_delta;
// attrib.EventData.m_sapphire_delta = request.m_sapphire_delta;
// attrib.EventData.m_current_epoch = request.m_current_epoch;
// attrib.EventData.m_current_inflation_rate = request.m_current_inflation_rate;
// attrib.Status = isRetry ? CaliumEventStatus.Regist : CaliumEventStatus.Failed;
//
// await m_dynamo_db_client.simpleInsertDocumentWithDocType(doc);
// return request.m_event_id;
// }
//
// }

View File

@@ -0,0 +1,28 @@
// namespace BrokerCore.Repository;
//
// using ServerCommon;
//
// public class CaliumStorageDocRepo
// {
// private readonly DynamoDbClient m_dynamo_db_client;
//
// public CaliumStorageDocRepo(DynamoDbClient dynamoDbClient)
// {
// m_dynamo_db_client = dynamoDbClient;
// }
//
// public async Task<(Result, CaliumStorageAttrib?)> findOne(string userGuid)
// {
// var (result_pk, primary_key_object) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumStorageDoc>(userGuid);
// if (result_pk.isFail() || primary_key_object == null)
// {
// return (result_pk, null);
// }
//
// var config = m_dynamo_db_client.makeQueryConfigForReadByPKOnly(primary_key_object.PK);
// var (result, doc) =
// await m_dynamo_db_client.simpleQueryDocTypeWithQueryOperationConfig<CaliumStorageDoc>(config);
// var attrib = doc?.getAttrib<CaliumStorageAttrib>();
// return (result, attrib);
// }
// }

View File

@@ -0,0 +1,30 @@
// namespace BrokerCore.Repository;
//
// using Common;
//
// using ServerCommon;
//
// public class CaliumStorageRepo
// {
// private readonly DynamoDbClient m_dynamo_db_client;
//
// public CaliumStorageRepo(DynamoDbClient dynamoDbClient)
// {
// m_dynamo_db_client = dynamoDbClient;
// }
//
// public async Task<(Result, CaliumStorageAttrib?)> findOne(string userGuid)
// {
// var (result_pk, primary_key_object) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumStorageDoc>(userGuid);
// if (result_pk.isFail() || primary_key_object == null)
// {
// return (result_pk, null);
// }
//
// var config = m_dynamo_db_client.makeQueryConfigForReadByPKOnly(primary_key_object.PK);
// var (result, doc) =
// await m_dynamo_db_client.simpleQueryDocTypeWithQueryOperationConfig<CaliumStorageDoc>(config);
// var attrib = doc?.getAttrib<CaliumStorageAttrib>();
// return (result, attrib);
// }
// }

View File

@@ -0,0 +1,445 @@
// using Amazon.DynamoDBv2;
// using Amazon.DynamoDBv2.Model;
//
// using ServerCommon;
//
// using ServerCore; using ServerBase;
//
// namespace BrokerCore.Repository;
//
// using BrokerApiServer.Common;
//
// public class BrokerApiLogActor : ILogActor
// {
// public string getActorGuid() => "broker";
// }
//
// public class BrokerApiWithLogActor : EntityBase, IWithLogActor
// {
// public readonly EntityType m_entity_type = EntityType.Money;
//
// public BrokerApiWithLogActor() : base(EntityType.Money)
// {
// }
//
// //public BrokerApiWithLogActor(string masterGuid) : base(EntityType.Money, masterGuid)
// //{
// //}
//
// public ILogActor toLogActor()
// {
// return new BrokerApiLogActor();
// }
// }
//
// public class DbqChangeSapphire : QueryExecutorBase
// {
// private readonly double m_delta;
// private PrimaryKey? m_primary_key;
// private readonly string m_user_guid;
//
// public DbqChangeSapphire(string userGuid, double delta) : base(nameof(DbqChangeSapphire))
// {
// m_delta = delta;
// m_user_guid = userGuid;
// }
//
// public override async Task<Result> onPrepareQuery()
// {
// (var result, m_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<MoneyDoc>(m_user_guid);
// return result;
// }
//
// public override async Task<Result> onQuery()
// {
// var owner = getOwner();
//
// // 부모 인스턴스의 정보를 사용하여 필요한 데이터를 가져온다. (여기서는 ...)
// var query_batch = getQueryBatch() as QueryBatch<QueryRunnerWithItemRequest>;
// NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {owner.toBasicString()}");
//
// var query_runner_with_item_request = query_batch.getQueryRunner();
// NullReferenceCheckHelper.throwIfNull(query_runner_with_item_request,
// () => $"query_runner_with_item_request is null !!! - {owner.toBasicString()}");
//
// var db_connector = query_batch.getDynamoDbConnector();
// var (result, update_request) = makeUpdateItemRequest();
// if (result.isFail())
// {
// return result;
// }
//
// NullReferenceCheckHelper.throwIfNull(update_request,
// () => $"update_request is null !!! - {owner.toBasicString()}");
//
// var exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(
// DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LackOfTotalCalium);
//
// var query_context = update_request.createItemRequestQueryContext(QueryType.Update, exception_handler);
// return await query_runner_with_item_request.tryRegisterQueryContext(query_context);
// }
//
// //=====================================================================================
// // DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
// //=====================================================================================
// public override Task onQueryResponseCommit()
// {
// return Task.CompletedTask;
// }
//
// //=====================================================================================
// // DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
// //=====================================================================================
// public override Task onQueryResponseRollback(Result errorResult)
// {
// return Task.CompletedTask;
// }
//
// private (Result, UpdateItemRequest?) makeUpdateItemRequest()
// {
// Guard.Against.isNull(m_primary_key, (BrokerApiErrorCode)ServerErrorCode.DynamoDbPrimaryKeyNotFound, "primary key is null");
// var attribute_value_with_primary_key = m_primary_key.toKeyWithAttributeValue();
//
// var currency_name = MoneyAttribExtensions.getKeyNameFromType(CurrencyType.Sapphire);
// var result = new Result();
// var dynamo_db_client = getQueryBatch()?.getDynamoDbConnector();
// NullReferenceCheckHelper.throwIfNull(dynamo_db_client, () => $"dynamo_db_client is null !!!");
//
// var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(dynamo_db_client.getTableName());
// query_builder.withKeys(attribute_value_with_primary_key);
//
// var target_doc = new MoneyDoc();
// var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
// var target_key = JsonHelper.getJsonPropertyName<MoneyAttrib>(currency_name);
// var (is_success, attribute_expression) =
// DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, target_key);
// if (false == is_success)
// {
// var err_msg =
// $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{target_key}";
// result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
// Log.getLogger().error(result.toBasicString());
//
// return (result, null);
// }
//
// query_builder.withExpressionAttributeNames(
// DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, target_key));
//
// var update_expression = (m_delta >= 0)
// ? $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) + :changeValue"
// : $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) - :changeValue";
// query_builder.withUpdateExpression(update_expression);
//
// var expression_attribute_values = new Dictionary<string, AttributeValue>
// {
// { ":changeValue", new AttributeValue { N = Math.Abs(m_delta).ToString() } },
// { ":start", new AttributeValue { N = "0" } }
// };
// query_builder.withExpressionAttributeValues(expression_attribute_values);
// query_builder.withReturnValues(ReturnValue.ALL_NEW);
// return query_builder.build();
// }
// }
//
// public class MoneyDocRepo
// {
// private readonly DynamoDbClient m_dynamo_db_client;
//
// public MoneyDocRepo(DynamoDbClient dynamoDbClient)
// {
// m_dynamo_db_client = dynamoDbClient;
// }
//
// public async Task<(Result, MoneyDoc?)> findMoneyDoc(string userGuid)
// {
// var (result, primary_key_object) = await DynamoDBDocBaseHelper.makePrimaryKey<MoneyDoc>(userGuid);
// if (result.isFail() || primary_key_object == null)
// {
// return (result, null);
// }
//
// var config = m_dynamo_db_client.makeQueryConfigForReadByPKOnly(primary_key_object.PK);
// return await m_dynamo_db_client.simpleQueryDocTypeWithQueryOperationConfig<MoneyDoc>(config);
// }
//
// public async Task<(Result, MoneyAttrib?)> findMoneyAttrib(string userGuid, CancellationToken cancellationToken)
// {
// var (result, doc) = await findMoneyDoc(userGuid);
// return (result, doc?.getAttrib<MoneyAttrib>());
// }
//
// public async Task<(Result, MoneyAttrib?)> changeSapphire(string userGuid, double delta)
// {
// var (result, make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<MoneyDoc>(userGuid);
// // 프라이머리 키 생성 실패
// if (result.isFail() || make_primary_key == null)
// {
// return (result, null);
// }
//
// (result, var request) = makeUpdateItemRequest(
// make_primary_key.toKeyWithAttributeValue(),
// MoneyAttribExtensions.getKeyNameFromType(CurrencyType.Sapphire),
// delta);
// // 업데이트 쿼리 생성 실패
// if (result.isFail() || request == null)
// {
// return (result, null);
// }
//
// (result, var update_doc) = await m_dynamo_db_client.simpleQueryDocTypesWithUpdateItemRequest<MoneyDoc>(request);
// // 업데이트 쿼리 실패
// if (result.isFail() || update_doc == null) return (result, null);
//
// var attrib = update_doc.getAttrib<MoneyAttrib>();
// // 업데이트 된 문서에서 MoneyAttrib을 찾을 수 없음
// if (attrib == null)
// {
// result.setFail(ServerErrorCode.AttribNotFound, $"attrib is null !!!");
// return (result, null);
// }
// return (result, attrib);
// }
//
// private async Task<Result> sendQuery(QueryBatchBase batch)
// {
// var result = new Result();
// var err_msg = string.Empty;
//
// if (batch == null)
// {
// err_msg = $"Failed to sendQuery !!!, QueryBatchBase is null";
// result.setFail(ServerErrorCode.FunctionInvalidParam, err_msg);
// return result;
// }
//
// if (false == batch.hasQuery())
// {
// err_msg = $"Not has DBQuery !!!";
// result.setFail(ServerErrorCode.DynamoDbQueryNoRequested, err_msg);
// return result;
// }
//
// result = await batch.prepareQueryWithStopwatch();
// if (result.isFail())
// {
// return result;
// }
//
// result = await batch.doQueryWithStopwatch();
// if (result.isFail())
// {
// return result;
// }
//
// return result;
// }
//
// private (Result, UpdateItemRequest?) makeUpdateItemRequest(
// Dictionary<string, AttributeValue> attributeValueWithPrimaryKey
// , string targetAttribName
// , double deltaCount)
// {
// var result = new Result();
// var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(m_dynamo_db_client.getTableName());
// query_builder.withKeys(attributeValueWithPrimaryKey);
//
// var target_doc = new MoneyDoc();
// var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
// var target_key = JsonHelper.getJsonPropertyName<MoneyAttrib>(targetAttribName);
// var (is_success, attribute_expression) =
// DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, target_key);
// if (false == is_success)
// {
// var err_msg =
// $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{target_key}";
// result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
// Log.getLogger().error(result.toBasicString());
// return (result, null);
// }
//
// query_builder.withExpressionAttributeNames(
// DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, target_key));
//
// var update_expression = (deltaCount >= 0)
// ? $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) + :changeValue"
// : $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) - :changeValue";
// query_builder.withUpdateExpression(update_expression);
//
// var expression_attribute_values = new Dictionary<string, AttributeValue>
// {
// { ":changeValue", new AttributeValue { N = Math.Abs(deltaCount).ToString() } },
// { ":start", new AttributeValue { N = "0" } }
// };
// query_builder.withExpressionAttributeValues(expression_attribute_values);
// query_builder.withReturnValues(ReturnValue.ALL_NEW);
// return query_builder.build();
// }
//
// // //=============================================================================================
// // // delta 만큼 금전을 변경(음수, 양수) 한다.
// // //=============================================================================================
// // public async Task<Result> changeMoney(CurrencyType currencyType, double delta, bool isTrimExcess = false,
// // bool useCaliumEvent = true)
// // {
// // var result = new Result();
// //
// // // var owner = getOwner() as Player;
// // // NullReferenceCheckHelper.throwIfNull(owner, () => $"player is null !!!");
// //
// // // if (currencyType == CurrencyType.Beam)
// // // {
// // // var found_transaction_runner = owner.findTransactionRunner(TransactionIdType.PrivateContents);
// // // found_transaction_runner?.addRemoteChargeAIPoint(this, delta);
// // // return result;
// // // }
// //
// // result = changeMoneyFromCurrencyType(currencyType, delta, isTrimExcess);
// // if (result.isSuccess() && useCaliumEvent)
// // {
// // var found_transaction_runner = owner.findTransactionRunner(TransactionIdType.PrivateContents);
// // var event_name = found_transaction_runner?.getTransactionName() ?? "None";
// // found_transaction_runner?.addNotifyCaliumEvent(this, event_name, currencyType, delta);
// // }
// //
// // return await Task.FromResult(result);
// // }
// //
// // private Result changeMoneyFromCurrencyType(CurrencyType type, double delta, bool isTrimExcess = false)
// // {
// // var result = new Result();
// // var err_msg = string.Empty;
// //
// // // var owner = getOwner() as Player;
// // // NullReferenceCheckHelper.throwIfNull(owner, () => $"player is null !!!");
// //
// // if (MetaData.Instance._CurrencyMetaTableByCurrencyType.TryGetValue(type, out var currencyMetaData) == false)
// // {
// // // err_msg = $"Not found CurrencyMetaData !!! : currencyType:{type} - {owner.toBasicString()}";
// // result.setFail(ServerErrorCode.CurrencyMetaDataNotFound, err_msg);
// // Log.getLogger().error(result.toBasicString());
// //
// // return result;
// // }
// //
// // // var money_attribute = owner.getEntityAttribute<MoneyAttribute>();
// // // NullReferenceCheckHelper.throwIfNull(money_attribute,
// // // () => $"money_attribute is null !!! - {owner.toBasicString()}");
// //
// // var currency = money_attribute.getCurrencyFromType(type);
// // var change = currency + delta;
// // if (change < 0)
// // {
// // err_msg =
// // $"Failed to change getCurrencyFromType() !!!, not enough Money : deltaMoney:{delta}, changeCurrency:{change}, currencyType:{type} - {owner.toBasicString()}";
// // result.setFail(ServerErrorCode.MoneyNotEnough, err_msg);
// // Log.getLogger().error(result.toBasicString());
// //
// // return result;
// // }
// //
// // if (change >= currencyMetaData.MaxCount)
// // {
// // MoneyNotifyHelper.send_GS2C_NTF_CURRENCY_MAX_ALERT(owner, type, currencyMetaData.MaxCount);
// //
// // if (change > currencyMetaData.MaxCount
// // && false == isTrimExcess)
// // {
// // err_msg =
// // $"Money exceeded Max Count !!! : toDelta:{delta}, toChange:{change} <= MaxCount:{currencyMetaData.MaxCount}, currencyType:{type} - {owner.toBasicString()}";
// // result.setFail(ServerErrorCode.MoneyMaxCountExceeded, err_msg);
// // Log.getLogger().error(result.toBasicString());
// //
// // return result;
// // }
// //
// // var trim_money = change - currencyMetaData.MaxCount;
// // change = double.Min(change, currencyMetaData.MaxCount);
// //
// // err_msg =
// // $"Exceeded MaxCount of Money !!!, Trimming Money : currencyType:{type}, changeMoney:{change}, trimMoney:{trim_money}, deltaMoney:{delta}, maxMoney:{currencyMetaData.MaxCount} - {owner.toBasicString()}";
// // Log.getLogger().info(err_msg);
// // }
// //
// // money_attribute.setCurrencyFromType(type, change);
// //
// // money_attribute.modifiedEntityAttribute();
// //
// // return result;
// // }
// //
// //
// // public TransactionRunner? findTransactionRunner(TransactionIdType transactionIdType)
// // {
// // TransactionRunner? found_transaction_runner = null;
// //
// // var err_msg = string.Empty;
// //
// // if (true == hasMasterGuid())
// // {
// // var master_guid = getMasterGuid();
// // var found_master_entity = onGetMasterEntity();
// // if(null == found_master_entity)
// // {
// // return null;
// // }
// //
// // found_transaction_runner = found_master_entity.findTransactionRunner(transactionIdType);
// // }
// // else
// // {
// // if (false == m_transaction_runners.TryGetValue(transactionIdType, out found_transaction_runner))
// // {
// // return null;
// // }
// // }
// //
// // return found_transaction_runner;
// // }
//
// // private (Result, UpdateItemRequest?) makeUpdateItemRequest(
// // Dictionary<string, AttributeValue> attributeValueWithPrimaryKey
// // , string targetAttribName
// // , double deltaCount)
// // {
// // var result = new Result();
// //
// // var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(m_dynamo_db_client.getTableName());
// // query_builder.withKeys(attributeValueWithPrimaryKey);
// //
// // var target_doc = new MoneyDoc();
// // var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
// // var target_key = JsonHelper.getJsonPropertyName<MoneyAttrib>(targetAttribName);
// // (var is_success, var attribute_expression) =
// // DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, target_key);
// // if (false == is_success)
// // {
// // var err_msg =
// // $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{target_key}";
// // result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
// // Log.getLogger().error(result.toBasicString());
// //
// // return (result, null);
// // }
// //
// // query_builder.withExpressionAttributeNames(
// // DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, target_key));
// //
// // var update_expression = (deltaCount >= 0)
// // ? $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) + :changeValue"
// // : $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) - :changeValue";
// // query_builder.withUpdateExpression(update_expression);
// //
// // var expression_attribute_values = new Dictionary<string, AttributeValue>
// // {
// // { ":changeValue", new AttributeValue { N = Math.Abs(deltaCount).ToString() } },
// // { ":start", new AttributeValue { N = "0" } }
// // };
// // query_builder.withExpressionAttributeValues(expression_attribute_values);
// //
// // query_builder.withReturnValues(ReturnValue.ALL_NEW);
// //
// // return query_builder.build();
// // }
// }

View File

@@ -0,0 +1,71 @@
// namespace BrokerCore.Repository;
//
// using DbEntity;
//
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Hosting;
//
// using ServerCommon;
//
// using ServerCore; using ServerBase;
//
// //==================================================
// // 행성 정보 캐시를 갱신한다.
// //==================================================
// public class PlanetInfoCache : BackgroundService
// {
// private readonly object m_lock = new();
// private IEnumerable<PlanetInfo> m_planets = [];
// private readonly IServiceScopeFactory m_scope_factory;
//
// public PlanetInfoCache(IServiceScopeFactory scopeFactory, IHostApplicationLifetime lifetime)
// {
// m_scope_factory = scopeFactory;
// }
//
// public IEnumerable<PlanetInfo> Planets
// {
// get
// {
// lock (m_planets)
// {
// return m_planets;
// }
// }
// }
//
// protected override async Task ExecuteAsync(CancellationToken stoppingToken)
// {
// while (!stoppingToken.IsCancellationRequested)
// {
// try
// {
// await updateData();
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// throw;
// }
//
// await Task.Delay(TimeSpan.FromSeconds(120), stoppingToken); // 120초마다 데이터 갱신
// }
// }
//
// private async Task updateData()
// {
// using var scope = m_scope_factory.CreateScope();
// var planet_info_repo = scope.ServiceProvider.GetRequiredService<PlanetInfoRepo>();
// var (result, planet_infos) = await planet_info_repo.findAll();
// if (result.isFail() || planet_infos == null)
// {
// Log.getLogger().error("Failed to find planet infos");
// return;
// }
//
// lock (m_lock)
// {
// m_planets = planet_infos;
// }
// }
// }

View File

@@ -0,0 +1,67 @@
// using ServerCommon;
//
// namespace BrokerCore.Repository;
//
// using ServerCore; using ServerBase;
//
// public class UserBaseDocRepo
// {
// private readonly DynamoDbClient m_dynamo_db_client;
//
// public UserBaseDocRepo(DynamoDbClient dynamoDbClient)
// {
// this.m_dynamo_db_client = dynamoDbClient;
// }
//
// public async Task<(Result, UserBaseDoc?)> findUserBaseDoc(string userGuid)
// {
// var (result, primary_key_object) = await DynamoDBDocBaseHelper.makePrimaryKey<UserBaseDoc>(userGuid);
// if (result.isFail() || primary_key_object == null)
// {
// return (result, null);
// }
//
// var config = m_dynamo_db_client.makeQueryConfigForReadByPKOnly(primary_key_object.PK);
// // var (result, user_doc) = await m_dynamoDbClient.simpleQueryDocTypeWithQueryOperationConfig<UserBaseDoc>(config);
// return await m_dynamo_db_client.simpleQueryDocTypeWithQueryOperationConfig<UserBaseDoc>(config);
// }
//
// public async Task<(Result, UserBaseAttrib?)> findUserBaseAttrib(string userGuid)
// {
// var (result, doc) = await findUserBaseDoc(userGuid);
// return (result, doc?.getAttrib<UserBaseAttrib>());
// }
//
// public async Task<(Result, string)> findNickname(string userGuid)
// {
// var (result, found_nickname_attrib) = await NicknameDoc.findNicknameFromGuid(m_dynamo_db_client, userGuid);
// if(result.isFail())
// {
// return (result, string.Empty);
// }
// NullReferenceCheckHelper.throwIfNull(found_nickname_attrib, () => $"found_nickname_attrib is null !!!, userGuid:{userGuid}");
// return (result, found_nickname_attrib.Nickname);
// }
//
// //===================================================================================================
// // 로그아웃 여부만 체크
// // TODO: 레디스 캐시를 이용하여 로그인 여부를 체크하는 것이 더 효율적일 수 있음
// //===================================================================================================
// public bool isUserLoggedIn(UserBaseAttrib userAttrib)
// {
// return userAttrib.GameLoginDateTime > userAttrib.GameLogoutDateTime;
// }
//
// // public async Task<Result> insertUserBaseDoc(UserBaseAttrib userAttrib)
// // {
// // var user_doc = new UserBaseDoc(userAttrib.UserGuid);
// // var user_attrib = user_doc.getAttrib<UserBaseAttrib>();
// // NullReferenceCheckHelper.throwIfNull(user_attrib, () => $"insertUserBaseDoc : user_attrib is null !!! - {userAttrib.UserGuid}");
// // user_attrib.UserGuid = userAttrib.UserGuid;
// // user_attrib.AccountId = userAttrib.AccountId;
// // user_attrib.EOA = userAttrib.EOA;
// // user_attrib.SelectedCharacterGuid = userAttrib.SelectedCharacterGuid;
// // user_attrib.IsIntroCompleted = userAttrib.IsIntroCompleted;
// // return await m_dynamoDbClient.simpleInsertDocumentWithDocType(user_doc);
// // }
// }

View File

@@ -0,0 +1,4 @@
public static class TestDefines
{
public static string MetaDataPath => Path.GetFullPath("../../../../../bin/Debug/resource/meta", Directory.GetCurrentDirectory());
}

View File

@@ -0,0 +1,16 @@
namespace BrokerTest.Helper;
public class MetaTableTestHelper
{
readonly BrokerApiMetaLoader m_meta_loader = new();
public void load()
{
m_meta_loader.load(TestDefines.MetaDataPath);
}
public BrokerMetaTableRef getMetaTableRef()
{
return new BrokerMetaTableRef(m_meta_loader.getMetaTable());
}
}

View File

@@ -0,0 +1,8 @@
namespace BrokerTest.Helper;
public static class TestConst
{
public const string TestPlanetId = "new_earth";
public const string TestPlanetSecret = "A8h$KmP";
public const string TestUserGuid = "1052b08b52ef4d69a27ee1f40911a72f";
}

View File

@@ -0,0 +1,37 @@
namespace BrokerTest.Helper;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using Xunit.Abstractions;
public class TestLogger<T> : ILogger<T>, IDisposable
{
private readonly List<string> m_logs = [];
private readonly ITestOutputHelper m_output;
public TestLogger(ITestOutputHelper output)
{
m_output = output;
}
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
return null;
}
public bool IsEnabled(LogLevel logLevel) => true;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
Func<TState, Exception?, string> formatter)
{
var message = formatter(state, exception);
m_logs.Add(message);
m_output.WriteLine(message);
}
public IEnumerable<string> Logs => m_logs;
public void Dispose() => m_logs.Clear();
}

View File

@@ -0,0 +1,70 @@
using BrokerApiServer.Extensions;
using BrokerCore;
using BrokerCore.Entity;
using BrokerCore.Repository;
using BrokerCore.Services;
using ServerCommon;
using ServerCore; using ServerBase;
namespace BrokerTest.Helper;
public class TestUserHelper
{
readonly BrokerServerLogic m_server_logic;
private readonly UserAuthAction m_auth_action;
private readonly PlanetUserEntity m_planet_user;
public TestUserHelper(string serviceEnv)
{
AppBuilderExtensions.initGlobalNlog();
Log.initLog("BrokerApiServer", "Developer");
var config = initBrokerServerConfig(serviceEnv);
var logic = new BrokerServerLogic(config);
logic.onInit().Wait();
ServerLogicApp.setServerLogicApp(logic);
m_server_logic = logic;
m_planet_user = new PlanetUserEntity(logic);
m_planet_user.onInit().Wait();
m_auth_action = new UserAuthAction(m_planet_user, logic.getDynamoDbClient());
}
private static ServerConfigMetaverseBroker initBrokerServerConfig(string serviceEnv)
{
string config_path = serviceEnv switch
{
"Dev" => "ServerConfig.json",
"QA" => "ServerConfig-QA.json",
"Stage" => "ServerConfig-Stage.json",
_ => throw new ArgumentException($"Invalid service environment: {serviceEnv}")
};
// 서버 설정
var server_config = new ServerConfigMetaverseBroker();
var server_config_path = $"./Config/{config_path}";
server_config.setConfigFilePath(server_config_path);
var result = server_config.tryLoadConfig().GetAwaiter().GetResult();
Assert.True(result.isSuccess(), $"ServerConfig Load Failed => {result}");
return server_config;
}
public async Task<string> getUserGuidByAccountId(string accountId)
{
try
{
var result = await m_auth_action.findAndSetAllAttributeByAccountId(accountId);
return result.isFail() ? string.Empty : m_planet_user.UserGuid;
}
catch (Exception ex)
{
Log.getLogger().Error(ex, $"{nameof(TestUserHelper)}.getUserGuidByAccountId() Exception => {ex.Message}");
return string.Empty;
}
}
}

View File

@@ -0,0 +1,18 @@
// namespace BrokerCore.Common;
//
// public class ValueResult<TValue>
// {
// public Result Result { get; init; }
// public TValue? Value { get; set; }
//
// public ValueResult()
// {
// Result = new Result();
// }
//
// public ValueResult(Result result, TValue? value)
// {
// Result = result;
// Value = value;
// }
// }