초기커밋
This commit is contained in:
283
ServerBase/Helper/DataCopyHelper.cs
Normal file
283
ServerBase/Helper/DataCopyHelper.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Amazon.Util.Internal;
|
||||
using Grpc.Core;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class DataCopyHelper
|
||||
{
|
||||
|
||||
#region 데이터 복사 하기 : Doc => Cache
|
||||
public static async Task<Result> copyCacheFromDocs<TCacheType>(TCacheType toCacheBase, List<DynamoDbDocBase> fromDocBases)
|
||||
where TCacheType : CacheBase
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toCacheBase as ICopyCacheFromDoc;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyCacheFromDoc !!! : {typeof(TCacheType).Name} !!!";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var doc in fromDocBases)
|
||||
{
|
||||
if (false == to_copy.copyCacheFromDoc(doc))
|
||||
{
|
||||
err_msg = $"Failed to copyCacheFromDoc() !!!, to:{typeof(TCacheType).Name}, from:{doc.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.DynamoDbDocCopyToCacheFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 데이터 복사 하기 : Doc => EntityAttribute
|
||||
public static async Task<Result> copyEntityAttributeFromDocs<TEntityAttributeType>(TEntityAttributeType toEntityAttributeBase, List<DynamoDbDocBase> fromDocBases)
|
||||
where TEntityAttributeType : EntityAttributeBase
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toEntityAttributeBase as ICopyEntityAttributeFromDoc;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyEntityAttributeFromDoc !!! : {typeof(TEntityAttributeType).Name}";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach(var doc in fromDocBases)
|
||||
{
|
||||
if (false == to_copy.copyEntityAttributeFromDoc(doc))
|
||||
{
|
||||
err_msg = $"Failed to copyEntityAttributeFromDoc() !!!, to:{typeof(TEntityAttributeType).Name}, from:{doc.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.DynamoDbDocCopyToEntityAttributeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 데이터 복사 하기 : Cache => EntityAttribute
|
||||
public static async Task<Result> copyEntityAttributeFromCaches<TEntityAttributeType>(TEntityAttributeType toEntityAttribBase, List<CacheBase> fromCacheBases)
|
||||
where TEntityAttributeType : EntityAttributeBase
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toEntityAttribBase as ICopyEntityAttributeFromCache;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyEntityAttributeFromCache !!! : {typeof(TEntityAttributeType).Name} !!!";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var cache in fromCacheBases)
|
||||
{
|
||||
if (false == to_copy.copyEntityAttributeFromCache(cache))
|
||||
{
|
||||
err_msg = $"Failed to copyEntityAttributeFromCache() !!!, to:{typeof(TEntityAttributeType).Name}, from:{cache.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.CacheCopyToEntityAttributeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 데이터 복사 하기 : Cache => Doc
|
||||
public static async Task<Result> copyDocFromCache<TDoc>(TDoc toDoc, List<CacheBase> fromCacheBases)
|
||||
where TDoc : DynamoDbDocBase
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toDoc as ICopyDocFromCache;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyDocFromCache !!! : {typeof(TDoc).Name}";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var cache in fromCacheBases)
|
||||
{
|
||||
if (false == to_copy.copyDocFromCache(cache))
|
||||
{
|
||||
err_msg = $"Failed to copyDocFromCache() !!!, to:{typeof(TDoc).Name}, from:{cache.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.CacheCopyToEntityAttributeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 데이터 복사 하기 : EntityAttribute => Cache
|
||||
public static async Task<Result> copyCacheFromEntityAttributes<TCacheType>(TCacheType toCacheBase, List<EntityAttributeBase> fromEntityAttributeBases)
|
||||
where TCacheType : CacheBase
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toCacheBase as ICopyCacheFromEntityAttribute;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyCacheFromEntityAttribute !!! : {typeof(TCacheType).Name} !!!";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach(var attribute in fromEntityAttributeBases)
|
||||
{
|
||||
if (false == to_copy.copyCacheFromEntityAttribute(attribute))
|
||||
{
|
||||
err_msg = $"Failed to copyCacheFromEntityAttributes() !!!, to:{typeof(TCacheType).Name}, from:{fromEntityAttributeBases.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.EntityAttributeCopyToCacheFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 데이터 복사 하기 : EntityAttribute => Doc
|
||||
public static async Task<Result> copyDocFromEntityAttributes<TDoc>(TDoc toDocBase, List<EntityAttributeBase> fromEntityAttributeBases)
|
||||
where TDoc : DynamoDbDocBase
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toDocBase as ICopyDocFromEntityAttribute;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyDocFromEntityAttribute !!! : {fromEntityAttributeBases.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var entity_attribute in fromEntityAttributeBases)
|
||||
{
|
||||
if (false == to_copy.copyDocFromEntityAttribute(entity_attribute))
|
||||
{
|
||||
err_msg = $"Failed to copyDocFromEntityAttribute() !!!, to:{typeof(TDoc).Name}, from:{fromEntityAttributeBases.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.EntityAttributeCopyToDynamoDbDocFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region 데이터 복사 하기 : EntityAttribute => EntityAttributeTransactor
|
||||
public static async Task<Result> copyEntityAttributeTransactorFromEntityAttribute<TEntityAttribute>(EntityAttributeTransactorBase<TEntityAttribute> toEntityAttributeTransactorBase, EntityAttributeBase fromEntityAttribute)
|
||||
where TEntityAttribute : EntityAttributeBase
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toEntityAttributeTransactorBase as ICopyEntityAttributeTransactorFromEntityAttribute;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyEntityAttributeTransactorBaseFromEntityAttribute !!! : {fromEntityAttribute.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (false == to_copy.copyEntityAttributeTransactorFromEntityAttribute(fromEntityAttribute))
|
||||
{
|
||||
err_msg = $"Failed to copyEntityAttributeTransactorBaseFromEntityAttribute() !!!, to:{toEntityAttributeTransactorBase.getTypeName()}, from:{fromEntityAttribute.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.EntityAttributeCopyToEntityAttributeTransactorFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 데이터 복사 하기 : EntityAttributeTransactor => Doc
|
||||
public static async Task<Result> copyDocFromEntityAttributeTransactor<TDynamoDbDocBase, TEntityAttribute>(TDynamoDbDocBase toDoc, EntityAttributeTransactorBase<TEntityAttribute> fromEntityAttributeTransactorBase)
|
||||
where TDynamoDbDocBase : DynamoDbDocBase
|
||||
where TEntityAttribute : EntityAttributeBase
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
var to_copy = toDoc as ICopyDocFromEntityAttributeTransactor;
|
||||
if (null == to_copy)
|
||||
{
|
||||
err_msg = $"Failed to cast ICopyDocFromEntityAttributeTransactor !!! : {fromEntityAttributeTransactorBase.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.ClassDoesNotImplementInterfaceInheritance, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (false == to_copy.copyDocFromEntityAttributeTransactor(fromEntityAttributeTransactorBase))
|
||||
{
|
||||
err_msg = $"Failed to copyDocFromEntityAttributeTransactor() !!!, to:{typeof(TDynamoDbDocBase).Name}, from:{fromEntityAttributeTransactorBase.getTypeName()}";
|
||||
result.setFail(ServerErrorCode.EntityAttributeTransactorCopyToDynamoDbDocFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
2505
ServerBase/Helper/DynamoDbClientHelper.cs
Normal file
2505
ServerBase/Helper/DynamoDbClientHelper.cs
Normal file
File diff suppressed because it is too large
Load Diff
1369
ServerBase/Helper/DynamoDbDocBaseHelper.cs
Normal file
1369
ServerBase/Helper/DynamoDbDocBaseHelper.cs
Normal file
File diff suppressed because it is too large
Load Diff
617
ServerBase/Helper/DynamoDbItemRequestHelper.cs
Normal file
617
ServerBase/Helper/DynamoDbItemRequestHelper.cs
Normal file
@@ -0,0 +1,617 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
using Amazon.DynamoDBv2;
|
||||
using Amazon.Runtime.Internal;
|
||||
using Amazon.DynamoDBv2.DocumentModel;
|
||||
using NLog.Conditions;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using DYNAMO_DB_TABLE_FULL_NAME = System.String;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class DynamoDbItemRequestHelper
|
||||
{
|
||||
public enum AttribValueAction
|
||||
{
|
||||
None = 0,
|
||||
|
||||
Increase, // Atomic 기반 증가
|
||||
Decrease, // Atomic 기반 감소
|
||||
Update // 값의 변경
|
||||
}
|
||||
|
||||
public class AttribAction
|
||||
{
|
||||
public AttribValueAction ValueAction { get; set; } = AttribValueAction.None;
|
||||
public AttributeValue Value { get; set; } = new();
|
||||
}
|
||||
|
||||
public static (Result, DynamoDbItemRequestQueryContext?) makeUpdateItemRequestWithDoc<TAttrib>( DynamoDbDocBase targetDoc
|
||||
, Dictionary<string, AttribAction> toChangeAttibValues
|
||||
, DynamoDbQueryExceptionNotifier.ExceptionHandler? exceptionHandler = null )
|
||||
where TAttrib : AttribBase
|
||||
{
|
||||
ConditionValidCheckHelper.throwIfFalseWithCondition(() => 0 < toChangeAttibValues.Count, () => $"Invalid toChangeAttibValues.Count !!! : 0 < {toChangeAttibValues.Count}");
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicApp();
|
||||
NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic client is null !!! ");
|
||||
var db_connector = server_logic.getDynamoDbClient();
|
||||
NullReferenceCheckHelper.throwIfNull(db_connector, () => $"db_connector client is null !!! ");
|
||||
|
||||
var result = new Result();
|
||||
|
||||
var primary_key = targetDoc.getPrimaryKey();
|
||||
|
||||
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(db_connector.getTableFullName(targetDoc.TableName));
|
||||
query_builder.withKeys(primary_key.toKeyWithAttributeValue());
|
||||
|
||||
var attrib_path_json_string = targetDoc.toJsonStringOfAttribs();
|
||||
|
||||
var update_expression = "SET ";
|
||||
var expression_idx = 0;
|
||||
var expression_attribute_names = new Dictionary<string, string>();
|
||||
var expression_attribute_values = new Dictionary<string, AttributeValue>();
|
||||
|
||||
var update_item_request = query_builder.getItemRequest();
|
||||
|
||||
foreach (var each in toChangeAttibValues)
|
||||
{
|
||||
var attrib_key = each.Key;
|
||||
var attrib_value = each.Value;
|
||||
|
||||
var target_key = JsonHelper.getJsonPropertyName<TAttrib>(attrib_key);
|
||||
(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} - {primary_key.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var attribute_names = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, target_key);
|
||||
foreach (var name in attribute_names)
|
||||
{
|
||||
expression_attribute_names.TryAdd(name.Key, name.Value);
|
||||
}
|
||||
|
||||
if (expression_idx > 0) update_expression += ", ";
|
||||
|
||||
var data = attrib_value.Value;
|
||||
if (AttribValueAction.Increase == attrib_value.ValueAction)
|
||||
{
|
||||
var start_key = $":start_{expression_idx}";
|
||||
var incr_key = $":incr_{expression_idx}";
|
||||
|
||||
update_expression += $"{attribute_expression} = if_not_exists({attribute_expression}, {start_key}) + {incr_key}";
|
||||
expression_attribute_values.Add(incr_key, data);
|
||||
expression_attribute_values.TryAdd(start_key, new AttributeValue { N = "0" });
|
||||
}
|
||||
else if(AttribValueAction.Decrease== attrib_value.ValueAction)
|
||||
{
|
||||
var start_key = $":start_{expression_idx}";
|
||||
var decr_key = $":decr_{expression_idx}";
|
||||
|
||||
update_expression += $"{attribute_expression} = if_not_exists({attribute_expression}, {start_key}) - {decr_key}";
|
||||
expression_attribute_values.Add(decr_key, data);
|
||||
expression_attribute_values.TryAdd(start_key, new AttributeValue { N = "0" });
|
||||
}
|
||||
else if (AttribValueAction.Update == attrib_value.ValueAction)
|
||||
{
|
||||
var new_value_key = $":newValue_{expression_idx}";
|
||||
|
||||
update_expression += $"{attribute_expression} = {new_value_key}";
|
||||
expression_attribute_values.Add(new_value_key, data);
|
||||
}
|
||||
|
||||
expression_idx++;
|
||||
}
|
||||
|
||||
query_builder.withExpressionAttributeNames(expression_attribute_names);
|
||||
query_builder.withUpdateExpression(update_expression);
|
||||
query_builder.withExpressionAttributeValues(expression_attribute_values);
|
||||
query_builder.withReturnValues(ReturnValue.ALL_NEW);
|
||||
|
||||
(result, var builded_update_item_request) = query_builder.build();
|
||||
if(result.isFail())
|
||||
{
|
||||
return (result, null);
|
||||
}
|
||||
NullReferenceCheckHelper.throwIfNull(builded_update_item_request, () => $"builded_update_item_request is null !!! - {primary_key.toBasicString()}");
|
||||
|
||||
var exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LackOfTotalCalium);
|
||||
|
||||
return (result, builded_update_item_request.createItemRequestQueryContext(QueryType.Update, exceptionHandler));
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================================
|
||||
// UpdateItemRequest Builder
|
||||
//=========================================================================================
|
||||
public class UpdateItemRequestBuilder
|
||||
{
|
||||
private readonly UpdateItemRequest m_request;
|
||||
|
||||
private Document? m_document;
|
||||
|
||||
private readonly bool m_is_upsert;
|
||||
|
||||
public UpdateItemRequestBuilder(DYNAMO_DB_TABLE_FULL_NAME tableFullName, bool isUpsert = false)
|
||||
{
|
||||
ConditionValidCheckHelper.throwIfFalseWithCondition(() => false == tableFullName.isNullOrWhiteSpace(), () => $"Invalid TableFullName !!!, Null or WhiteSpace !!!");
|
||||
|
||||
m_request = new UpdateItemRequest
|
||||
{
|
||||
TableName = tableFullName,
|
||||
Key = new Dictionary<string, AttributeValue>(),
|
||||
AttributeUpdates = new Dictionary<string, AttributeValueUpdate>(),
|
||||
UpdateExpression = string.Empty,
|
||||
};
|
||||
|
||||
m_is_upsert = isUpsert;
|
||||
}
|
||||
|
||||
public UpdateItemRequest getItemRequest() => m_request;
|
||||
|
||||
public UpdateItemRequestBuilder withDocument(Document document)
|
||||
{
|
||||
m_document = document;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withReturnValues(ReturnValue returnValue)
|
||||
{
|
||||
m_request.ReturnValues = returnValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withConditionExpression(string conditionExpression)
|
||||
{
|
||||
m_request.ConditionExpression = conditionExpression;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withExpressionAttributeNames(Dictionary<string, string> expressionAttributeNames)
|
||||
{
|
||||
m_request.ExpressionAttributeNames = expressionAttributeNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withExpressionAttributeValues(Dictionary<string, AttributeValue> expressionAttributeValues)
|
||||
{
|
||||
m_request.ExpressionAttributeValues = expressionAttributeValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withKeys(Dictionary<string, AttributeValue> keyValue)
|
||||
{
|
||||
m_request.Key = keyValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder addKey(string keyName, string keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { S = keyValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder addKey(string keyName, int keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder addKey(string keyName, long keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder addKey(string keyName, float keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder addKey(string keyName, double keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder addKey(string keyName, bool keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { BOOL = keyValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder addKey(string keyName, AttributeValue keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = keyValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withReturnConsumedCapacity(ReturnConsumedCapacity returnConsumedCapacity)
|
||||
{
|
||||
m_request.ReturnConsumedCapacity = returnConsumedCapacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withReturnItemCollectionMetrics(ReturnItemCollectionMetrics returnItemCollectionMetrics)
|
||||
{
|
||||
m_request.ReturnItemCollectionMetrics = returnItemCollectionMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withUpdateExpression(string updateExpression)
|
||||
{
|
||||
m_request.UpdateExpression = updateExpression;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateItemRequestBuilder withConditionCheck(string conditionExpression)
|
||||
{
|
||||
m_request.ConditionExpression = conditionExpression;
|
||||
return this;
|
||||
}
|
||||
|
||||
public (Result, UpdateItemRequest?) build()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
if(null != m_document)
|
||||
{
|
||||
result = m_document.tryFillupUpdateItemRequest(m_request, m_is_upsert);
|
||||
if(result.isFail())
|
||||
{
|
||||
return (result, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( false == m_is_upsert
|
||||
&& null != m_request.ConditionExpression
|
||||
&& m_request.ConditionExpression.isNullOrWhiteSpace() )
|
||||
{
|
||||
m_request.ConditionExpression = $"attribute_exists({PrimaryKey.PK_Define}) AND attribute_exists({PrimaryKey.SK_Define})";
|
||||
}
|
||||
}
|
||||
|
||||
return (result, m_request);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
// GetItemRequest Builder
|
||||
//=========================================================================================
|
||||
public class GetItemRequestBuilder
|
||||
{
|
||||
private readonly GetItemRequest m_request;
|
||||
public GetItemRequestBuilder(string tableName)
|
||||
{
|
||||
m_request = new GetItemRequest
|
||||
{
|
||||
TableName = tableName,
|
||||
Key = new Dictionary<string, AttributeValue>(),
|
||||
ExpressionAttributeNames = new Dictionary<string, string>()
|
||||
};
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder withKeys(Dictionary<string, AttributeValue> keyValue)
|
||||
{
|
||||
m_request.Key = keyValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder addKey(string keyName, string keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { S = keyValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder addKey(string keyName, int keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder addKey(string keyName, long keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder addKey(string keyName, double keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder addKey(string keyName, float keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder addKey(string keyName, bool keyValue)
|
||||
{
|
||||
m_request.Key[keyName] = new AttributeValue { BOOL = keyValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder withConsistentRead(bool isConsistentRead)
|
||||
{
|
||||
m_request.ConsistentRead = isConsistentRead;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder withProjectionExpression(string projectExpression)
|
||||
{
|
||||
m_request.ProjectionExpression = projectExpression;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder withExpressionAttributeNames(Dictionary<string, string> expressionAttributeNames)
|
||||
{
|
||||
m_request.ExpressionAttributeNames = expressionAttributeNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequestBuilder withReturnConsumedCapacity(ReturnConsumedCapacity returnConsumedCapacity)
|
||||
{
|
||||
m_request.ReturnConsumedCapacity = returnConsumedCapacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetItemRequest build()
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
// PutItemRequest Builder
|
||||
//=========================================================================================
|
||||
public class PutItemRequestBuilder
|
||||
{
|
||||
private readonly PutItemRequest m_request;
|
||||
|
||||
public PutItemRequestBuilder(string tableName)
|
||||
{
|
||||
m_request = new PutItemRequest
|
||||
{
|
||||
TableName = tableName,
|
||||
Item = new Dictionary<string, AttributeValue>(),
|
||||
ExpressionAttributeNames = new Dictionary<string, string>(),
|
||||
ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
|
||||
};
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withItem(Dictionary<string, AttributeValue> attributeValues)
|
||||
{
|
||||
m_request.Item = attributeValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder addItem(string keyName, string keyValue)
|
||||
{
|
||||
m_request.Item[keyName] = new AttributeValue { S = keyValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder addItem(string keyName, int keyValue)
|
||||
{
|
||||
m_request.Item[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder addItem(string keyName, long keyValue)
|
||||
{
|
||||
m_request.Item[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder addItem(string keyName, double keyValue)
|
||||
{
|
||||
m_request.Item[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder addItem(string keyName, float keyValue)
|
||||
{
|
||||
m_request.Item[keyName] = new AttributeValue { N = keyValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder addItem(string keyName, bool keyValue)
|
||||
{
|
||||
m_request.Item[keyName] = new AttributeValue { BOOL = keyValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withConditionalOperator(ConditionalOperator conditionalOperator)
|
||||
{
|
||||
m_request.ConditionalOperator = conditionalOperator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withConditionalCapacity(ReturnConsumedCapacity returnConsumedCapacity)
|
||||
{
|
||||
m_request.ReturnConsumedCapacity = returnConsumedCapacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withConditionExpression(string conditionExpression)
|
||||
{
|
||||
m_request.ConditionExpression = conditionExpression;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withExpressionAttributeNames(Dictionary<string, string> expressAttributeNames)
|
||||
{
|
||||
m_request.ExpressionAttributeNames = expressAttributeNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withExpressionAttributeValues(Dictionary<string, AttributeValue> expressAttributeValues)
|
||||
{
|
||||
m_request.ExpressionAttributeValues = expressAttributeValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withReturnConsumedCapacity(ReturnConsumedCapacity retrunConsumedCapacity)
|
||||
{
|
||||
m_request.ReturnConsumedCapacity = retrunConsumedCapacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequestBuilder withReturnItemCollectionMetrics(ReturnItemCollectionMetrics returnItemCollectionMetrics)
|
||||
{
|
||||
m_request.ReturnItemCollectionMetrics = returnItemCollectionMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PutItemRequest build()
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
// DeleteItemRequest Builder
|
||||
//=========================================================================================
|
||||
public class DeleteItemRequestBuilder
|
||||
{
|
||||
private readonly DeleteItemRequest m_request;
|
||||
|
||||
public DeleteItemRequestBuilder(string tableName)
|
||||
{
|
||||
m_request = new DeleteItemRequest
|
||||
{
|
||||
TableName = tableName,
|
||||
Key = new Dictionary<string, AttributeValue>(),
|
||||
ExpressionAttributeNames = new Dictionary<string, string>(),
|
||||
ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
|
||||
};
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withKeys(Dictionary<string, AttributeValue> keys)
|
||||
{
|
||||
m_request.Key = keys;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder addKey(string attributeName, string attributeValue)
|
||||
{
|
||||
m_request.Key[attributeName] = new AttributeValue { S = attributeValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder addKey(string attributeName, int attributeValue)
|
||||
{
|
||||
m_request.Key[attributeName] = new AttributeValue { N = attributeValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder addKey(string attributeName, long attributeValue)
|
||||
{
|
||||
m_request.Key[attributeName] = new AttributeValue { N = attributeValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder addKey(string attributeName, double attributeValue)
|
||||
{
|
||||
m_request.Key[attributeName] = new AttributeValue { N = attributeValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder addKey(string attributeName, float attributeValue)
|
||||
{
|
||||
m_request.Key[attributeName] = new AttributeValue { N = attributeValue.ToString() };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder addKey(string attributeName, bool attributeValue)
|
||||
{
|
||||
m_request.Key[attributeName] = new AttributeValue { BOOL = attributeValue };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withConditionalOperator(ConditionalOperator conditionalOperator)
|
||||
{
|
||||
m_request.ConditionalOperator = conditionalOperator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withReturnValues(ReturnValue returnValue)
|
||||
{
|
||||
m_request.ReturnValues = returnValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withConditionExpression(string conditionExpression)
|
||||
{
|
||||
m_request.ConditionExpression = conditionExpression;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withExpressionAttributeNames(Dictionary<string, string> expressionAttributeNames)
|
||||
{
|
||||
m_request.ExpressionAttributeNames = expressionAttributeNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withExpressionAttributeValues(Dictionary<string, AttributeValue> expressionAttributeValues)
|
||||
{
|
||||
m_request.ExpressionAttributeValues = expressionAttributeValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withReturnConsumedCapacity(ReturnConsumedCapacity returnConsumedCapacity)
|
||||
{
|
||||
m_request.ReturnConsumedCapacity = returnConsumedCapacity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequestBuilder withReturnItemCollectionMetrics(ReturnItemCollectionMetrics returnItemCollectionMetrics)
|
||||
{
|
||||
m_request.ReturnItemCollectionMetrics = returnItemCollectionMetrics;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeleteItemRequest build()
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
}
|
||||
|
||||
public static DynamoDbItemRequestQueryContext createItemRequestQueryContext( this AmazonDynamoDBRequest itemRequest
|
||||
, QueryType queryType
|
||||
, DynamoDbQueryExceptionNotifier.ExceptionHandler? exceptionHandler = null)
|
||||
{
|
||||
return new DynamoDbItemRequestQueryContext(itemRequest, queryType, exceptionHandler);
|
||||
}
|
||||
|
||||
public static bool isValid(this AmazonDynamoDBRequest itemRequest)
|
||||
{
|
||||
//if (document.getPK() == string.Empty || document.getSK() == string.Empty || document.getDocType() == string.Empty)
|
||||
//{
|
||||
// Log.getLogger().error($"PK or SK or DocType is empty !!! : {document.toBasicString()}");
|
||||
// return false;
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
256
ServerBase/Helper/DynamoDbStopwatchHelper.cs
Normal file
256
ServerBase/Helper/DynamoDbStopwatchHelper.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
|
||||
|
||||
using Amazon.DynamoDBv2;
|
||||
using Amazon.DynamoDBv2.DocumentModel;
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class DynamoDbStopwatchHelper
|
||||
{
|
||||
public static Search queryWithStopwatch(this Table table, QueryOperationConfig queryOperationConfig, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
var search = table.Query(queryOperationConfig);
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - Table Query Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec} - {table.toBasicString()}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
|
||||
return search;
|
||||
}
|
||||
|
||||
public static async Task putItemAsyncWithStopwatch(this Table table, Document document, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
await table.PutItemAsync(document);
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - Table PutItemAsync Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec} - {table.toBasicString()}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Document?> upsertItemAsyncWithStopwatch(this Table table, Document document, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
var updated_document = await table.UpdateItemAsync(document);
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - Table UpsertItemAsync Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec} - {table.toBasicString()}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
|
||||
return updated_document;
|
||||
}
|
||||
|
||||
public static async Task<Document?> updateItemAsyncWithStopwatch(this Table table, Document document, UpdateItemOperationConfig operationConfig, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
var updated_document = await table.UpdateItemAsync(document, operationConfig);
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - Table UpdateItemAsync Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec} - {table.toBasicString()}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
|
||||
return updated_document;
|
||||
}
|
||||
|
||||
public static async Task deleteItemAsyncWithStopwatch(this Table table, Document document, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
await table.DeleteItemAsync(document);
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - Table DeleteItemAsync Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec} - {table.toBasicString()}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task executeAsyncWithStopwatch(this DocumentBatchWrite batch, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
await batch.ExecuteAsync();
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - DocumentBatchWrite ExecuteAsync Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task executeAsyncWithStopwatch(this DocumentTransactWrite transactWrite, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
await transactWrite.ExecuteAsync();
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - DocumentTransactWrite ExecuteAsync Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<UpdateItemResponse> updateItemAsyncWithStopwatch(this AmazonDynamoDBClient dbClient, UpdateItemRequest updateItemRequest, string eventTid)
|
||||
{
|
||||
Stopwatch? stopwatch = null;
|
||||
|
||||
var server_logic = ServerLogicApp.getServerLogicAppWithNull();
|
||||
var server_config = server_logic?.getServerConfig();
|
||||
|
||||
if (true == server_config?.PerformanceCheckEnable)
|
||||
{
|
||||
eventTid = string.IsNullOrEmpty(eventTid) ? System.Guid.NewGuid().ToString("N") : eventTid;
|
||||
stopwatch = Stopwatch.StartNew();
|
||||
}
|
||||
|
||||
var updated_item_response = await dbClient.UpdateItemAsync(updateItemRequest);
|
||||
|
||||
if (null != stopwatch)
|
||||
{
|
||||
var elapsed_msec = stopwatch.ElapsedMilliseconds;
|
||||
stopwatch.Stop();
|
||||
|
||||
if (elapsed_msec > Constant.STOPWATCH_LOG_LIMIT_MSEC)
|
||||
{
|
||||
Log.getLogger().debug($"QueryBatch - DocumentTransactWrite ExecuteAsync Stopwatch Stop : ETID:{eventTid}, ElapsedMSec:{elapsed_msec} - {updateItemRequest.toBasicString()}");
|
||||
}
|
||||
|
||||
Monitor.It.setDelayTimeForDBResponse(elapsed_msec);
|
||||
}
|
||||
|
||||
return updated_item_response;
|
||||
}
|
||||
}
|
||||
25
ServerBase/Helper/EntityHelper.cs
Normal file
25
ServerBase/Helper/EntityHelper.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
|
||||
public static class EntityHelper
|
||||
{
|
||||
public static Pos makePos( float x, float y, float z
|
||||
, int angle )
|
||||
{
|
||||
var pos = new Pos();
|
||||
pos.X = x;
|
||||
pos.Y = y;
|
||||
pos.Z = z;
|
||||
pos.Angle = angle;
|
||||
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
46
ServerBase/Helper/ErrorHelper.cs
Normal file
46
ServerBase/Helper/ErrorHelper.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
//=============================================================================================
|
||||
// 오류 관련 각종 지원 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//=============================================================================================
|
||||
|
||||
public static class ErrorHelper
|
||||
{
|
||||
public static bool isSuccess(this ServerErrorCode error)
|
||||
{
|
||||
if(ServerErrorCode.Success == error)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool isFail(this ServerErrorCode error)
|
||||
{
|
||||
if (ServerErrorCode.Success != error)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string toBasicString(this ServerErrorCode error)
|
||||
{
|
||||
return $"ErrorCode:{error.ToString()}";
|
||||
}
|
||||
}
|
||||
86
ServerBase/Helper/HttpClientHelper.cs
Normal file
86
ServerBase/Helper/HttpClientHelper.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class HttpClientHelper
|
||||
{
|
||||
public static async Task<(bool, string)> sendHttpRequest( string httpMethod
|
||||
, string url
|
||||
, string? jwt
|
||||
, string? bodyJson
|
||||
, string mediaType
|
||||
, string userAgentName
|
||||
, string userAgentVersion
|
||||
, short timeOutSec = 5 )
|
||||
{
|
||||
validateUserAgentArgs(mediaType, userAgentName, userAgentVersion);
|
||||
|
||||
Log.getLogger().debug($"Request Message To WebServer. url : {url}, httpMethod : {httpMethod}, jwt : {jwt}, bodyJson : {bodyJson}");
|
||||
|
||||
var requestMessage = new HttpRequestMessage(new HttpMethod(httpMethod), url);
|
||||
|
||||
if (!string.IsNullOrEmpty(jwt))
|
||||
{
|
||||
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", jwt);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(bodyJson))
|
||||
{
|
||||
requestMessage.Content = new StringContent(bodyJson, Encoding.UTF8, mediaType);
|
||||
}
|
||||
|
||||
requestMessage.Headers.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue(userAgentName, userAgentVersion));
|
||||
|
||||
try
|
||||
{
|
||||
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeOutSec)))
|
||||
{
|
||||
var resMsg = await SharedHttpClient.It.sendAsync(requestMessage, cts.Token);
|
||||
if (resMsg == null)
|
||||
{
|
||||
Log.getLogger().error($"resMsg is null, sendAsync() returned null - url:{url}");
|
||||
return (false, string.Empty);
|
||||
}
|
||||
|
||||
var readMsg = await resMsg.Content.ReadAsStringAsync();
|
||||
Log.getLogger().debug($"Response Message From sendAsync() : readMsg:{readMsg} - url:{url}");
|
||||
|
||||
if (!resMsg.IsSuccessStatusCode)
|
||||
{
|
||||
return (false, readMsg);
|
||||
}
|
||||
|
||||
return (true, readMsg);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
Log.getLogger().error($"OperationCanceledException !!!, Request timed out !!! : exception:{e} - url:{url}");
|
||||
return (false, "Request Timeout");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.getLogger().error($"Exception !!!, Failed to perform in sendHttpRequest() : exception:{e} - - url:{url}");
|
||||
return (false, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateUserAgentArgs(string mediaType, string userAgentName, string userAgentVersion)
|
||||
{
|
||||
if (mediaType.isNullOrWhiteSpace())
|
||||
throw new ArgumentException("mediaType must be a non-empty string.", nameof(mediaType));
|
||||
|
||||
if (userAgentName.isNullOrWhiteSpace())
|
||||
throw new ArgumentException("userAgentName must be a non-empty string.", nameof(userAgentName));
|
||||
|
||||
if (userAgentVersion.isNullOrWhiteSpace())
|
||||
throw new ArgumentException("userAgentVersion must be a non-empty string.", nameof(userAgentVersion));
|
||||
}
|
||||
}
|
||||
97
ServerBase/Helper/MySqlConnectorHelper.cs
Normal file
97
ServerBase/Helper/MySqlConnectorHelper.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using MySqlConnector;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
//=============================================================================================
|
||||
// MySqlConnector 관련 각종 지원 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//=============================================================================================
|
||||
public static class MySqlConnectorHelper
|
||||
{
|
||||
public static async Task<Result> simpleTryConnectToDb(string connectionString)
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
using (var db_connector = new MySqlDbConnector())
|
||||
{
|
||||
var error_cdoe = await db_connector.initMySql(connectionString);
|
||||
if (error_cdoe.isFail())
|
||||
{
|
||||
err_msg = $"Failed to initMySql() !!! : errCode:{error_cdoe} - connectString:{connectionString}";
|
||||
result.setFail(error_cdoe, err_msg);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async Task<Result> simpleQueryExecuteForReaderAsync( string queryString, Func<MySqlDataReader, ServerErrorCode> readFunc
|
||||
, string connectionString
|
||||
, Int16 queryTimeoutSec = 15
|
||||
, Int16 retryIntervalMSec = 1000, Int16 retryCount = 3 )
|
||||
{
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
using ( var db_connector = new MySqlDbConnector() )
|
||||
{
|
||||
for(var i = 0; i <= retryCount; i++)
|
||||
{
|
||||
var error_cdoe = await db_connector.initMySql(connectionString);
|
||||
if (error_cdoe.isSuccess())
|
||||
{
|
||||
error_cdoe = await db_connector.querySQL(queryString, readFunc);
|
||||
if(error_cdoe.isSuccess())
|
||||
{
|
||||
// 성공하면 즉시 반환 한다 !!!
|
||||
result.setSuccess();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Db와 연결이 끊어진 경우는 재시도 설정에 따라 추가 처리 한다.
|
||||
if (ConnectionState.Closed == db_connector.getLastConnectionState())
|
||||
{
|
||||
err_msg = $"Failed to retry Open MySql !!! : errCode:{error_cdoe}";
|
||||
result.setFail(error_cdoe, err_msg);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
await Task.Delay(retryIntervalMSec);
|
||||
|
||||
err_msg = $"Retry Query !!! : retriedCount:{i}, queryString:{queryString} - retryableCount:{retryCount}";
|
||||
Log.getLogger().error(err_msg);
|
||||
}
|
||||
}
|
||||
// 기타 오류 발생시 실패로 처리 한다.
|
||||
else
|
||||
{
|
||||
err_msg = $"Failed to simpleQueryExecuteForReaderAsync() !!! : errCode:{error_cdoe}, queryString:{queryString} - retryCount:{retryCount}";
|
||||
Log.getLogger().error(err_msg);
|
||||
result.setFail(error_cdoe, err_msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
16
ServerBase/Helper/MySqlHelper.cs
Normal file
16
ServerBase/Helper/MySqlHelper.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using MySqlConnector;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class MySqlHelper
|
||||
{
|
||||
public static string makeConnectionString(string server, string id, string passward, string database)
|
||||
{
|
||||
return $"Server={server};User ID={id};Password={passward};Database={database}";
|
||||
}
|
||||
}
|
||||
138
ServerBase/Helper/ProgramVersionHelper.cs
Normal file
138
ServerBase/Helper/ProgramVersionHelper.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using NLog.LayoutRenderers.Wrappers;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class ProgramVersionHelper
|
||||
{
|
||||
public static ServerErrorCode checkClientProgramVersion( ServerConfig config
|
||||
, ServerProgramVersion serverProgramVersion
|
||||
, ClientProgramVersion clientVersion )
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(config, $"config is null !!!");
|
||||
ArgumentNullException.ThrowIfNull(serverProgramVersion, $"serverProgramVersion is null !!!");
|
||||
|
||||
var err_msg = string.Empty;
|
||||
|
||||
if (null == clientVersion)
|
||||
{
|
||||
err_msg = $"ClientProgramVersion is null !!!";
|
||||
Log.getLogger().error(err_msg);
|
||||
return ServerErrorCode.ClientProgramVersionIsNull;
|
||||
}
|
||||
|
||||
var version_paths = config.getVersionPaths();
|
||||
ArgumentNullException.ThrowIfNull(version_paths, $"version_paths is null !!!");
|
||||
|
||||
foreach ( var each in version_paths )
|
||||
{
|
||||
var version_type = each.Key;
|
||||
|
||||
switch(version_type)
|
||||
{
|
||||
case ProgramVersionType.MetaSchemaVersion:
|
||||
if (serverProgramVersion.MetaSchemaVersion != clientVersion.MetaSchemaVersion)
|
||||
{
|
||||
err_msg = $"Not match MetaSchema Version !!! : serverMetaSchemaVersion:{serverProgramVersion.MetaSchemaVersion} == clientMetaSchemaVersion:{clientVersion.MetaSchemaVersion}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return ServerErrorCode.MetaSchemaVersionNotMatch;
|
||||
}
|
||||
break;
|
||||
|
||||
case ProgramVersionType.MetaDataVersion:
|
||||
if (serverProgramVersion.MetaDataVersion != clientVersion.MetaDataVersion)
|
||||
{
|
||||
err_msg = $"Not match MetaData Version !!! : serverMetaDataVersion:{serverProgramVersion.MetaDataVersion} == clientMetaDataVersion:{clientVersion.MetaDataVersion}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return ServerErrorCode.MetaDataVersionNotMatch;
|
||||
}
|
||||
break;
|
||||
|
||||
case ProgramVersionType.PacketVersion:
|
||||
if (serverProgramVersion.PacketVersion != clientVersion.PacketVersion)
|
||||
{
|
||||
err_msg = $"Not match Packet Version !!! : serverPacketVersion:{serverProgramVersion.PacketVersion} == clientPacketVersion:{clientVersion.PacketVersion}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return ServerErrorCode.PacketVersionNotMatch;
|
||||
}
|
||||
break;
|
||||
|
||||
case ProgramVersionType.ResourceVersion:
|
||||
if (serverProgramVersion.ResourceVersion != clientVersion.ResourceVersion)
|
||||
{
|
||||
err_msg = $"Not match ResourceVersion Version !!! : serverPacketVersion:{serverProgramVersion.ResourceVersion} == clientResourceVersion:{clientVersion.ResourceVersion}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return ServerErrorCode.ResourceVersionNotMatch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (config.ClientMinimumRequiredLogicVersion > clientVersion.LogicVersion)
|
||||
{
|
||||
err_msg = $"Not match ClientLogic Version !!! : ClientMinimumRequiredLogicVersion:{config.ClientMinimumRequiredLogicVersion} <= clientLogicVersion:{clientVersion.LogicVersion}";
|
||||
Log.getLogger().error(err_msg);
|
||||
return ServerErrorCode.ClientLogicVersionNotMatch;
|
||||
}
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
|
||||
public static Result appendVersion( this ServerProgramVersion programVersion
|
||||
, ProgramVersionType versionType
|
||||
, Int32 buildVersion, Int32 revisionVersion )
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
switch(versionType)
|
||||
{
|
||||
case ProgramVersionType.MetaSchemaVersion:
|
||||
programVersion.MetaSchemaVersion = (ulong)revisionVersion;
|
||||
break;
|
||||
|
||||
case ProgramVersionType.MetaDataVersion:
|
||||
programVersion.MetaDataVersion = (ulong)revisionVersion;
|
||||
break;
|
||||
|
||||
case ProgramVersionType.DbSchemaVersion:
|
||||
programVersion.DbSchemaVersion = (ulong)revisionVersion;
|
||||
break;
|
||||
|
||||
case ProgramVersionType.PacketVersion:
|
||||
programVersion.PacketVersion = (ulong)revisionVersion;
|
||||
break;
|
||||
|
||||
case ProgramVersionType.ResourceVersion:
|
||||
programVersion.ResourceVersion = (ulong)revisionVersion;
|
||||
break;
|
||||
|
||||
case ProgramVersionType.ConfigVersion:
|
||||
programVersion.ConfigVersion = (ulong)revisionVersion;
|
||||
break;
|
||||
|
||||
case ProgramVersionType.LogicVersion:
|
||||
var logic_version = new LogicVersion();
|
||||
programVersion.LogicVersion = logic_version;
|
||||
logic_version.Revision = revisionVersion;
|
||||
break;
|
||||
|
||||
default:
|
||||
var err_msg = $"Invaoid ProgramVersionType !!! : ProgramVersionType:{versionType}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
187
ServerBase/Helper/ProtoHelper.cs
Normal file
187
ServerBase/Helper/ProtoHelper.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.Collections;
|
||||
using Google.Protobuf.Reflection;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Microsoft.AspNetCore.DataProtection.KeyManagement;
|
||||
using RabbitMQ.Client.Events;
|
||||
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
//=============================================================================================
|
||||
// Protobuf 관련 각종 지원 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//=============================================================================================
|
||||
|
||||
public static class ProtoHelper
|
||||
{
|
||||
public static string toBasicString(this IMessage _this)
|
||||
{
|
||||
// IM : IMessage
|
||||
return $"IM: {_this.ToString()}";
|
||||
}
|
||||
|
||||
public static string toBasicString(this FieldDescriptor _this)
|
||||
{
|
||||
// FD : FieldDescriptor
|
||||
return $"FD: {_this.ToString()}";
|
||||
}
|
||||
|
||||
public static string toJson(this IMessage message)
|
||||
{
|
||||
return JsonFormatter.Default.Format(message);
|
||||
}
|
||||
|
||||
public static List<T> toList<T>(this RepeatedField<T> repeatedField)
|
||||
{
|
||||
return new List<T>(repeatedField);
|
||||
}
|
||||
|
||||
public static RepeatedField<T> toRepeatedField<T>(this List<T> list)
|
||||
{
|
||||
var repeated_field = new RepeatedField<T>();
|
||||
repeated_field.AddRange(list);
|
||||
return repeated_field;
|
||||
}
|
||||
|
||||
public static Dictionary<TKey, TValue> toDictionary<TKey, TValue>(this MapField<TKey, TValue> mapField)
|
||||
where TKey : notnull
|
||||
where TValue : notnull
|
||||
{
|
||||
var dictionary = new Dictionary<TKey, TValue>();
|
||||
foreach (var each in mapField)
|
||||
{
|
||||
dictionary.Add(each.Key, each.Value);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public static MapField<TKey, TValue> toMapField<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
|
||||
where TKey : notnull
|
||||
where TValue : notnull
|
||||
{
|
||||
var map_field = new MapField<TKey, TValue>();
|
||||
foreach (var each in dictionary)
|
||||
{
|
||||
map_field.Add(each.Key, each.Value);
|
||||
}
|
||||
return map_field;
|
||||
}
|
||||
|
||||
private static IMessage? parsePacketActionType(this IMessage rootMsg)
|
||||
{
|
||||
var found_oneof = rootMsg.Descriptor.Oneofs.First<OneofDescriptor>();
|
||||
if (null == found_oneof)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var curr_oneof_field = found_oneof.Accessor.GetCaseFieldDescriptor(rootMsg);
|
||||
if (null == curr_oneof_field)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var packet_action_type = (IMessage)curr_oneof_field.Accessor.GetValue(rootMsg);
|
||||
if (null == packet_action_type)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return packet_action_type;
|
||||
}
|
||||
|
||||
private static IMessage? parsePacketCommandType(this IMessage childMsg)
|
||||
{
|
||||
var found_oneof = childMsg.Descriptor.Oneofs.First<OneofDescriptor>();
|
||||
if (null == found_oneof)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var curr_oneof_field = found_oneof.Accessor.GetCaseFieldDescriptor(childMsg);
|
||||
if (null == curr_oneof_field)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var packet_command_type = (IMessage)curr_oneof_field.Accessor.GetValue(childMsg);
|
||||
if (null == packet_command_type)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return packet_command_type;
|
||||
}
|
||||
|
||||
private static bool parsePacketCommandMsgHook(this IMessage message)
|
||||
{
|
||||
var message_hook_property = message.GetType().GetProperty("MessageHook");
|
||||
if (message_hook_property != null)
|
||||
{
|
||||
var msgHookValue = message_hook_property.GetValue(message);
|
||||
if (msgHookValue is bool)
|
||||
{
|
||||
return (bool)msgHookValue;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool makeProudNetPacketCommand(this IMessage message, out ProudNetPacketCommand? packetCommand)
|
||||
{
|
||||
packetCommand = null;
|
||||
|
||||
var packet_action_type = message.parsePacketActionType();
|
||||
if (null == packet_action_type)
|
||||
{
|
||||
Log.getLogger().fatal($"Not found Packet Action Type !!! : {message.toBasicString()}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var packet_command_type = parsePacketCommandType(packet_action_type);
|
||||
if (null == packet_command_type)
|
||||
{
|
||||
Log.getLogger().fatal($"Not found Packet Command Type !!! : {message.toBasicString()}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var msg_hook = parsePacketCommandMsgHook(packet_command_type);
|
||||
|
||||
packetCommand = new ProudNetPacketCommand(packet_action_type.GetType(), packet_command_type.GetType());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool makeRabbitMqPacketCommand(this IMessage message, BasicDeliverEventArgs ea, out RabbitMqPacketCommand? packetCommand)
|
||||
{
|
||||
packetCommand = null;
|
||||
|
||||
var packet_command_type = message.parsePacketCommandType();
|
||||
if (null == packet_command_type)
|
||||
{
|
||||
ServerCore.Log.getLogger().fatal($"Not found Packet Command Type !!! : {message.toBasicString()}");
|
||||
return false;
|
||||
}
|
||||
|
||||
packetCommand = new RabbitMqPacketCommand(ea.Exchange, packet_command_type.GetType());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
41
ServerBase/Helper/ProudNetHelper.cs
Normal file
41
ServerBase/Helper/ProudNetHelper.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Google.Protobuf;
|
||||
using Nettention.Proud;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using SESSION_ID = System.Int32;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
// ProudNet 관련 각종 지원 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//=============================================================================================
|
||||
|
||||
public static class ProudNetHelper
|
||||
{
|
||||
public static void convertP2PGroupToByteArray(ByteArray byArray, P2PGroupType p2PGroupType)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var output = new CodedOutputStream(stream))
|
||||
{
|
||||
p2PGroupType.WriteTo(output);
|
||||
}
|
||||
byArray.AddRange(stream.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
88
ServerBase/Helper/ResultHelper.cs
Normal file
88
ServerBase/Helper/ResultHelper.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
//=============================================================================================
|
||||
// Result 관련 확장 함수
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//=============================================================================================
|
||||
|
||||
public static class ResultHelper
|
||||
{
|
||||
public static bool isSuccess(this Result result)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
if (true == result.ErrorCode.isSuccess())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool isFail(this Result result)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
if (true == result.ErrorCode.isFail())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setSuccess(this Result result, string resultString = "")
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
result.set(ServerErrorCode.Success, resultString);
|
||||
}
|
||||
|
||||
public static void setFail(this Result result, ServerErrorCode errorCode, string resultString = "")
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
result.set(errorCode, resultString);
|
||||
}
|
||||
|
||||
public static string getResultString(this Result result)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
return result.ResultString;
|
||||
}
|
||||
|
||||
public static ServerErrorCode getErrorCode(this Result result)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
return result.ErrorCode;
|
||||
}
|
||||
|
||||
public static void set(this Result result, ServerErrorCode errorCode, string resultString)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
result.ErrorCode = errorCode;
|
||||
result.ResultString = resultString;
|
||||
}
|
||||
|
||||
public static string toBasicString(this Result result)
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(result, () => $"result is null !!!");
|
||||
|
||||
return $"ErrorInfo: errCode:{result.getErrorCode()}, errDesc:{result.getResultString()}";
|
||||
}
|
||||
}
|
||||
212
ServerBase/Helper/ServerConfigHelper.cs
Normal file
212
ServerBase/Helper/ServerConfigHelper.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
|
||||
using NLog.Layouts;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Axion.Collections.Concurrent;
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using DYNAMO_DB_TABLE_NAME = System.String;
|
||||
using DYNAMO_DB_TABLE_FULL_NAME = System.String;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static partial class ServerConfigHelper
|
||||
{
|
||||
private static ServerConfig? m_server_config;
|
||||
|
||||
private static Flags<AuthRule.FlagType> m_auth_rules_flags = new();
|
||||
private static Dictionary<Tuple<ServerType, ServerType>, LoadBalancingRule.Config> m_load_balancing_rule_configs = new();
|
||||
|
||||
public static void init(ServerConfig serverConfig)
|
||||
{
|
||||
m_server_config = serverConfig;
|
||||
|
||||
initAuthRule(serverConfig);
|
||||
initLoadBalancingRule(serverConfig);
|
||||
}
|
||||
|
||||
public static int getDefaultMaxUser()
|
||||
{
|
||||
NullReferenceCheckHelper.throwIfNull(m_server_config, () => $"m_server_config is null !!!");
|
||||
return m_server_config.DefaultMaxUser;
|
||||
}
|
||||
|
||||
private static void initAuthRule(ServerConfig serverConfig)
|
||||
{
|
||||
var auth_rule = serverConfig.AuthRule;
|
||||
|
||||
m_auth_rules_flags.setFlag(AuthRule.FlagType.BotIdAllow, auth_rule.BotIdAllow);
|
||||
m_auth_rules_flags.setFlag(AuthRule.FlagType.TestIdAllow, auth_rule.TestIdAllow);
|
||||
m_auth_rules_flags.setFlag(AuthRule.FlagType.ClientStandaloneAllow, auth_rule.ClientStandaloneAllow);
|
||||
m_auth_rules_flags.setFlag(AuthRule.FlagType.ClientBySsoAccountAuthWithLauncherAllow, auth_rule.ClientBySsoAccountAuthWithLauncherAllow);
|
||||
}
|
||||
|
||||
public static string getSsoAccountDbConnectionString(this ServerConfig serverConfig)
|
||||
{
|
||||
return serverConfig.SsoAccountDb;
|
||||
}
|
||||
|
||||
private static void initLoadBalancingRule(ServerConfig serverConfig)
|
||||
{
|
||||
var load_balancing_rule = serverConfig.LoadBalancingRule;
|
||||
|
||||
m_load_balancing_rule_configs.Add(Tuple.Create<ServerType, ServerType>(ServerType.Login, ServerType.Channel), load_balancing_rule.AuthToGameRule);
|
||||
m_load_balancing_rule_configs.Add(Tuple.Create<ServerType, ServerType>(ServerType.Channel, ServerType.Indun), load_balancing_rule.ChannelToInstanceDungeonRule);
|
||||
m_load_balancing_rule_configs.Add(Tuple.Create<ServerType, ServerType>(ServerType.Indun, ServerType.Channel), load_balancing_rule.InstanceDungeonToChannelRule);
|
||||
m_load_balancing_rule_configs.Add(Tuple.Create<ServerType, ServerType>(ServerType.Channel, ServerType.Channel), load_balancing_rule.ChannelToChannelRule);
|
||||
}
|
||||
|
||||
public static LoadBalancingRule.Config? getLoadBalancingRuleType(ServerType fromServerType, ServerType toServerType)
|
||||
{
|
||||
m_load_balancing_rule_configs.TryGetValue(Tuple.Create<ServerType, ServerType>(fromServerType, toServerType), out var rule_config);
|
||||
if(null == rule_config)
|
||||
{
|
||||
rule_config = m_server_config?.LoadBalancingRule.ToEtcServerRule;
|
||||
}
|
||||
|
||||
return rule_config;
|
||||
}
|
||||
|
||||
public static string geAccountNftDbConnectionString(this ServerConfig serverConfig)
|
||||
{
|
||||
return serverConfig.AccountNftDb;
|
||||
}
|
||||
|
||||
public static List<PlatformType> toPlatformTypeAllows(this string platformTypeAllows)
|
||||
{
|
||||
var platform_type_allows = new List<PlatformType>();
|
||||
|
||||
var splitted_value = platformTypeAllows.Split(",");
|
||||
for(int i = 0; i < splitted_value.Length; i++)
|
||||
{
|
||||
var enum_string = splitted_value[i];
|
||||
|
||||
var platform_type = EnumHelper.convertEnumValueStringToEnum(enum_string, PlatformType.None);
|
||||
if(PlatformType.None != platform_type)
|
||||
{
|
||||
if(true == platform_type_allows.Exists(x => x == platform_type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
platform_type_allows.Add(platform_type);
|
||||
}
|
||||
}
|
||||
|
||||
return platform_type_allows;
|
||||
}
|
||||
|
||||
public static ServiceType toServiceType( this string serviceType, ServiceType defaultType)
|
||||
{
|
||||
return EnumHelper.convertEnumValueStringToEnum(serviceType, defaultType);
|
||||
}
|
||||
|
||||
public static DYNAMO_DB_TABLE_NAME makeDynamoDbTableFullName(string tableName, ServiceType serviceType)
|
||||
{
|
||||
ConditionValidCheckHelper.throwIfFalseWithCondition(() => false == tableName.isNullOrWhiteSpace(), () => $"Invalid tableName !!!");
|
||||
return tableName + "-" + serviceType.ToString();
|
||||
}
|
||||
|
||||
public static (ServerErrorCode, ConcurrentDictionary<DYNAMO_DB_TABLE_NAME, DYNAMO_DB_TABLE_FULL_NAME>) getDynamoDbTableNamesWithServiceType( string serviceType )
|
||||
{
|
||||
var target_table_names = new ConcurrentDictionary<DYNAMO_DB_TABLE_NAME, DYNAMO_DB_TABLE_FULL_NAME>();
|
||||
|
||||
// 서비스 타입 체크
|
||||
var enum_service_type = serviceType.convertEnumTypeAndValueStringToEnum<ServiceType>(ServiceType.None);
|
||||
if ( enum_service_type != ServiceType.Dev
|
||||
&& enum_service_type != ServiceType.Qa
|
||||
&& enum_service_type != ServiceType.Stage
|
||||
&& enum_service_type != ServiceType.Live )
|
||||
{
|
||||
return (ServerErrorCode.ServiceTypeInvalid, target_table_names);
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
// 기본 메인 테이블
|
||||
//=========================================================================================
|
||||
{
|
||||
var main_table_name = DynamoDbDefine.TableNames.Main;
|
||||
var table_full_name = ServerConfigHelper.makeDynamoDbTableFullName(main_table_name, enum_service_type);
|
||||
if(false == target_table_names.TryAdd(main_table_name, table_full_name)) { return (ServerErrorCode.DynamoDbTableNameDuplicated, target_table_names); }
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
// 기타 추가 DB
|
||||
//=========================================================================================
|
||||
|
||||
|
||||
return (ServerErrorCode.Success, target_table_names);
|
||||
}
|
||||
|
||||
public static string toClientListenIP(this ServerConfig _this)
|
||||
{
|
||||
return AwsHelper.getAwsPublicIPv4OrEthernetIPv4();
|
||||
}
|
||||
|
||||
public static UInt16 toClientListenPort(this ServerConfig _this)
|
||||
{
|
||||
if (0 >= _this.ClientListenPort)
|
||||
{
|
||||
return _this.getAppParamPort();
|
||||
}
|
||||
|
||||
return _this.ClientListenPort;
|
||||
}
|
||||
|
||||
public static ServerErrorCode fillupCloudWatchLogLayout(this JObject jsonObject, out JsonLayout jsonLayout)
|
||||
{
|
||||
JObject? json_object_with_layout = null;
|
||||
|
||||
if (JTokenType.Object == jsonObject.Type)
|
||||
{
|
||||
json_object_with_layout = jsonObject["Layout"] as JObject;
|
||||
}
|
||||
|
||||
if ( null == json_object_with_layout )
|
||||
{
|
||||
jsonLayout = new JsonLayout
|
||||
{
|
||||
Attributes =
|
||||
{
|
||||
new JsonAttribute("logTime", "${date:universalTime=true:format=yyyy-MM-ddTHH\\:mm\\:ss.fffZ}"),
|
||||
new JsonAttribute("server", "${event-properties:server}"),
|
||||
new JsonAttribute("ip/port", "${event-properties:ip/port}"),
|
||||
new JsonAttribute("threadId", "${threadid}"),
|
||||
new JsonAttribute("level", "${level:upperCase=true}"),
|
||||
new JsonAttribute("message", "${message}"),
|
||||
new JsonAttribute("function", "${event-properties:memberName}"),
|
||||
new JsonAttribute("filePath", "${event-properties:filePath}"),
|
||||
new JsonAttribute("lineNumber", "${event-properties:lineNumber}"),
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonLayout = new JsonLayout();
|
||||
|
||||
var ref_attributes = jsonLayout.Attributes;
|
||||
foreach (var property in json_object_with_layout.Properties())
|
||||
{
|
||||
if (JTokenType.Object != jsonObject.Type)
|
||||
{
|
||||
return ServerErrorCode.JsonTypeInvalid;
|
||||
}
|
||||
ref_attributes.Add(new JsonAttribute(property.Name, property.Value.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
return ServerErrorCode.Success;
|
||||
}
|
||||
}
|
||||
151
ServerBase/Helper/ServerHelper.cs
Normal file
151
ServerBase/Helper/ServerHelper.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class ServerHelper
|
||||
{
|
||||
public static Mutex m_server_running_mutex = new Mutex();
|
||||
|
||||
public static bool isValidServerType(this ServerType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ServerType.Channel:
|
||||
case ServerType.Login:
|
||||
case ServerType.Indun:
|
||||
case ServerType.Chat:
|
||||
case ServerType.Auth:
|
||||
case ServerType.Manager:
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
Log.getLogger().error($"Invalid ServerType !!! : ServerType:{type}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static LocationTargetType toLocationTargetType(this string serverType)
|
||||
{
|
||||
var server_type = EnumHelper.convertEnumValueStringToEnum<ServerType>(serverType, ServerType.None);
|
||||
switch (server_type)
|
||||
{
|
||||
case ServerType.Channel:
|
||||
return LocationTargetType.World;
|
||||
|
||||
case ServerType.Indun:
|
||||
return LocationTargetType.Instance;
|
||||
}
|
||||
|
||||
return LocationTargetType.None;
|
||||
}
|
||||
|
||||
public static ServerType toServerType(this string serverType)
|
||||
{
|
||||
return EnumHelper.convertEnumValueStringToEnum<ServerType>(serverType, ServerType.None);
|
||||
}
|
||||
|
||||
public static ServerType fillupServerType(string serverName)
|
||||
{
|
||||
var server_type = serverName.Split(":")[0];
|
||||
|
||||
return EnumHelper.convertEnumValueStringToEnum<ServerType>(server_type, ServerType.None);
|
||||
}
|
||||
|
||||
public static string toServerTypeString(this ServerType serverType)
|
||||
{
|
||||
return serverType.ToString();
|
||||
}
|
||||
|
||||
public static string toServerName(this ServerType type, string ip, UInt16 port, int worldId = 0, int channel = 0)
|
||||
{
|
||||
var server_type = type.ToString();
|
||||
var server_name = string.Empty;
|
||||
|
||||
if (false == type.isValidServerType())
|
||||
{
|
||||
server_name = makeServerNameByNetworkAddress(type, ip, port);
|
||||
Log.getLogger().error($"Failed to convert ServerName !!! : {server_name}");
|
||||
|
||||
return server_name;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ServerType.Channel:
|
||||
{
|
||||
server_name = makeGameServerName(type, worldId, channel);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
server_name = makeServerNameByNetworkAddress(type, ip, port);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return server_name;
|
||||
}
|
||||
|
||||
public static string makeGameServerName(ServerType type, int worldId, int channel)
|
||||
{
|
||||
return ($"{type.ToString()}:{ServerHelper.makeWorldIdToString(worldId)}:{ServerHelper.makeChannelToString(channel)}");
|
||||
}
|
||||
|
||||
public static string makeServerNameByNetworkAddress(ServerType type, string ip, UInt16 port)
|
||||
{
|
||||
return ($"{type.ToString()}:{ip}_{port.ToString()}");
|
||||
}
|
||||
|
||||
public static string makeWorldIdToString(int worldId)
|
||||
{
|
||||
return worldId.ToString("000");
|
||||
}
|
||||
|
||||
public static string makeChannelToString(int channel)
|
||||
{
|
||||
return channel.ToString("000");
|
||||
}
|
||||
|
||||
public static bool isRunningServerWithListenPort(this Process currProcess, UInt16 listenPort)
|
||||
{
|
||||
return isExistProcess(currProcess.ProcessName + Convert.ToString(listenPort));
|
||||
}
|
||||
|
||||
public static bool isExistProcess(string serverName)
|
||||
{
|
||||
m_server_running_mutex = new Mutex(true, serverName, out bool create_new);
|
||||
return create_new == true ? false : true;
|
||||
}
|
||||
|
||||
public static NetworkAddress toNetworkAddress(this ServerInfo serverInfo)
|
||||
{
|
||||
var network_address = new NetworkAddress();
|
||||
network_address.IP = serverInfo.Address;
|
||||
network_address.Port = (UInt16)serverInfo.Port;
|
||||
|
||||
return network_address;
|
||||
}
|
||||
|
||||
public static ClientToLoginMessage.Types.GameServerInfo toGameServerInfo(this NetworkAddress networkAddress)
|
||||
{
|
||||
var game_server_info = new ClientToLoginMessage.Types.GameServerInfo();
|
||||
game_server_info.GameServerAddr = networkAddress.IP;
|
||||
game_server_info.GameServerPort = networkAddress.Port;
|
||||
|
||||
return game_server_info;
|
||||
}
|
||||
}
|
||||
93
ServerBase/Helper/ServerLogicHelper.cs
Normal file
93
ServerBase/Helper/ServerLogicHelper.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using StackExchange.Redis;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
|
||||
|
||||
using MODULE_ID = System.UInt32;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class ServerLogicHelper
|
||||
{
|
||||
public static RabbitMQConnectorBase getRabbitMqConnector(this IServerLogic logic)
|
||||
{
|
||||
var found_module = logic.getModule((MODULE_ID)ModuleId.RabbitMqConnector);
|
||||
var casted_rabbit_mq_connector = found_module as RabbitMQConnectorBase;
|
||||
NullReferenceCheckHelper.throwIfNull(casted_rabbit_mq_connector, () => $"casted_rabbit_mq_connector is null !!! - {logic.toBasicString()}");
|
||||
return casted_rabbit_mq_connector;
|
||||
}
|
||||
|
||||
public static RedisConnector getRedisConnector(this IServerLogic logic)
|
||||
{
|
||||
var found_module = logic.getModule((MODULE_ID)ModuleId.RedisConnector);
|
||||
var casted_redis_connector = found_module as RedisConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(casted_redis_connector, () => $"casted_redis_connector is null !!! - {logic.toBasicString()}");
|
||||
return casted_redis_connector;
|
||||
}
|
||||
|
||||
public static IDatabase getRedisDb(this IServerLogic logic)
|
||||
{
|
||||
var redis_database = logic.getRedisConnector().getDatabase();
|
||||
NullReferenceCheckHelper.throwIfNull(redis_database, () => $"redis_database is null !!! - {logic.toBasicString()}");
|
||||
return redis_database;
|
||||
}
|
||||
|
||||
public static RedisWithLuaScriptExecutor getRedisWithLuaScriptExecutor(this IServerLogic logic)
|
||||
{
|
||||
var found_module = logic.getModule((MODULE_ID)ModuleId.RedisWithLuaScriptExecutor);
|
||||
var casted_redis_with_lua_script_executor = found_module as RedisWithLuaScriptExecutor;
|
||||
NullReferenceCheckHelper.throwIfNull(casted_redis_with_lua_script_executor, () => $"casted_redis_with_lua_script_executor is null !!! - {logic.toBasicString()}");
|
||||
return casted_redis_with_lua_script_executor;
|
||||
}
|
||||
|
||||
public static DynamoDbClient getDynamoDbClient(this IServerLogic logic)
|
||||
{
|
||||
var found_module = logic.getModule((MODULE_ID)ModuleId.DynamoDbConnector);
|
||||
var casted_dynamo_db_client = found_module as DynamoDbClient;
|
||||
NullReferenceCheckHelper.throwIfNull(casted_dynamo_db_client, () => $"casted_dynamo_db_client is null !!! - {logic.toBasicString()}");
|
||||
return casted_dynamo_db_client;
|
||||
}
|
||||
|
||||
public static MongoDbConnector getMongoDbConnector(this IServerLogic logic)
|
||||
{
|
||||
var found_module = logic.getModule((MODULE_ID)ModuleId.MongoDbConnector);
|
||||
var casted_mongo_db_connector = found_module as MongoDbConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(casted_mongo_db_connector, () => $"casted_mongo_db_connector is null !!! - {logic.toBasicString()}");
|
||||
return casted_mongo_db_connector;
|
||||
}
|
||||
|
||||
|
||||
public static S3Connector getS3Connector(this IServerLogic logic)
|
||||
{
|
||||
var found_module = logic.getModule((MODULE_ID)ModuleId.S3Connector);
|
||||
var casted_s3_connector = found_module as S3Connector;
|
||||
NullReferenceCheckHelper.throwIfNull(casted_s3_connector, () => $"casted_s3_connector is null !!! - {logic.toBasicString()}");
|
||||
return casted_s3_connector;
|
||||
}
|
||||
|
||||
public static ListenSessionBase getListenSessionBase(this ServerLogicBase logicBase)
|
||||
{
|
||||
var found_module = logicBase.getModule<IModule>((MODULE_ID)ModuleId.ProudNetListener);
|
||||
var listen_session_base = found_module as ListenSessionBase;
|
||||
NullReferenceCheckHelper.throwIfNull(listen_session_base, () => $"listen_session_base is null !!! - {logicBase.toBasicString()}");
|
||||
return listen_session_base;
|
||||
}
|
||||
|
||||
public static ListenSessionBase getListenSessionBaseByModuleId(this ServerLogicBase logicBase, ModuleId moduleId)
|
||||
{
|
||||
var found_module = logicBase.getModule<IModule>((MODULE_ID)moduleId);
|
||||
var listen_session_base = found_module as ListenSessionBase;
|
||||
NullReferenceCheckHelper.throwIfNull(listen_session_base, () => $"listen_session_base is null !!! - {logicBase.toBasicString()}");
|
||||
return listen_session_base;
|
||||
}
|
||||
}
|
||||
|
||||
172
ServerBase/Helper/ServerMetricsHelper.cs
Normal file
172
ServerBase/Helper/ServerMetricsHelper.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
|
||||
|
||||
using ServerCore;
|
||||
|
||||
|
||||
using MODULE_ID = System.UInt32;
|
||||
using WORLD_META_ID = System.UInt32;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
|
||||
public static class ServerMetricsHelper
|
||||
{
|
||||
public static async Task<(Result, ServerInfo?)> getServerInfoByChannel( this IWithServerMetrics serverMetrics
|
||||
, WORLD_META_ID worldMetaId, int channelNo )
|
||||
{
|
||||
var result = new Result();
|
||||
ServerInfo? found_server_info = null;
|
||||
|
||||
var server_metrics_request = serverMetrics.getServerMetricsCacheRequest();
|
||||
NullReferenceCheckHelper.throwIfNull(server_metrics_request, () => $"server_metrics_request is null - {serverMetrics.toBasicString()}");
|
||||
var handler_type = (uint)ServerMetricsCacheRequest.TriggerType.ServerMetrics_ChannelTargetGetAndFill;
|
||||
var with_result = await server_metrics_request.tryRunTriggerHandler(handler_type, worldMetaId, channelNo);
|
||||
if (with_result.Result.isFail())
|
||||
{
|
||||
return (with_result.Result, null);
|
||||
}
|
||||
|
||||
var result_value_server_info = with_result as ResultValue<ServerInfo>;
|
||||
NullReferenceCheckHelper.throwIfNull(result_value_server_info, () => $"result_value_server_info is null - {serverMetrics.toBasicString()}");
|
||||
if (null != result_value_server_info.ValueOfResult)
|
||||
{
|
||||
found_server_info = result_value_server_info.ValueOfResult;
|
||||
}
|
||||
|
||||
if (null != found_server_info)
|
||||
{
|
||||
return (result, found_server_info);
|
||||
}
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
public static async Task<(Result, ServerInfo?)> getServerInfoByServerName( this IWithServerMetrics serverMetrics
|
||||
, string serverName )
|
||||
{
|
||||
var result = new Result();
|
||||
ServerInfo? found_server_info = null;
|
||||
|
||||
var server_metrics_request = serverMetrics.getServerMetricsCacheRequest();
|
||||
NullReferenceCheckHelper.throwIfNull(server_metrics_request, () => $"server_metrics_request is null - {serverMetrics.toBasicString()}");
|
||||
var handler_type = (uint)ServerMetricsCacheRequest.TriggerType.ServerMetrics_GetByServerName;
|
||||
var with_result = await server_metrics_request.tryRunTriggerHandler(handler_type, serverName);
|
||||
if (with_result.Result.isFail())
|
||||
{
|
||||
return (with_result.Result, null);
|
||||
}
|
||||
|
||||
var result_value_server_info = with_result as ResultValue<ServerInfo>;
|
||||
NullReferenceCheckHelper.throwIfNull(result_value_server_info, () => $"result_value_server_info is null - {serverMetrics.toBasicString()}");
|
||||
if (null != result_value_server_info.ValueOfResult)
|
||||
{
|
||||
found_server_info = result_value_server_info.ValueOfResult;
|
||||
}
|
||||
|
||||
if (null != found_server_info)
|
||||
{
|
||||
return (result, found_server_info);
|
||||
}
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
public static async Task<(Result, List<ServerInfo>)> getServerInfosByServerType( this IWithServerMetrics serverMetrics
|
||||
, ServerType serverType, WORLD_META_ID worldMetaId = 0)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var server_metrics_request = serverMetrics.getServerMetricsCacheRequest();
|
||||
NullReferenceCheckHelper.throwIfNull(server_metrics_request, () => $"server_metrics_request is null - {serverMetrics.toBasicString()}");
|
||||
var handler_type = (uint)ServerMetricsCacheRequest.TriggerType.ServerMetrics_ServerTypeGetAndFill;
|
||||
var with_result = await server_metrics_request.tryRunTriggerHandler(handler_type, serverType, worldMetaId);
|
||||
if (with_result.Result.isFail())
|
||||
{
|
||||
return (with_result.Result, new List<ServerInfo>());
|
||||
}
|
||||
if (with_result.isResultOnly())
|
||||
{
|
||||
return (result, new List<ServerInfo>());
|
||||
}
|
||||
|
||||
var result_value_server_info = with_result as ResultValue<List<ServerInfo>>;
|
||||
NullReferenceCheckHelper.throwIfNull(result_value_server_info, () => $"result_value_server_info is null - {serverMetrics.toBasicString()}");
|
||||
|
||||
return (result, result_value_server_info.ValueOfResult);
|
||||
}
|
||||
|
||||
public static async Task<Result> syncServerInfoToCache( this IWithServerMetrics serverMetrics
|
||||
, string serverName
|
||||
, string listenIp, ushort listenPort
|
||||
, int currentConnectedUserCount
|
||||
, int maxUserCount
|
||||
, int reservationCount = 0, int returnUserCount = 0
|
||||
, int ugcNpcCount = 0
|
||||
, string awsInstanceId = ""
|
||||
, int worldId = 0, int channelNo = 0, int roomCapcity = 0 )
|
||||
{
|
||||
var err_msg = string.Empty;
|
||||
var result = new Result();
|
||||
|
||||
try
|
||||
{
|
||||
var server_metrics_request = serverMetrics.getServerMetricsCacheRequest();
|
||||
var server_info = server_metrics_request.makeServerInfo( serverName
|
||||
, listenIp, listenPort
|
||||
, currentConnectedUserCount, maxUserCount
|
||||
, reservationCount, returnUserCount
|
||||
, ugcNpcCount
|
||||
, worldId, channelNo, roomCapcity
|
||||
, awsInstanceId );
|
||||
|
||||
var handler_type = (uint)ServerMetricsCacheRequest.TriggerType.ServerMetrics_UpdateToCache;
|
||||
var with_result = await server_metrics_request.tryRunTriggerHandler(handler_type, serverName, server_info);
|
||||
if (with_result.Result.isFail())
|
||||
{
|
||||
err_msg = $"Failed to sync ServerInfo with Cache !!! : {with_result.Result.toBasicString()} - {serverMetrics.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return with_result.Result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var error_code = ServerErrorCode.TryCatchException;
|
||||
err_msg = $"Exception !!!, Failed to sync ServerInfo with Cache !!! : errorCode:{error_code}, exception:{e} - {serverMetrics.toBasicString()}";
|
||||
result.setFail(error_code, err_msg);
|
||||
Log.getLogger().error(err_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static ServerMetricsCacheRequest getServerMetricsCacheRequest(this IWithServerMetrics serverMetrics)
|
||||
{
|
||||
return ServerMetricsManager.It.getServerMetricsCacheRequest();
|
||||
}
|
||||
|
||||
public static bool isSetupCompleted(this ServerLogicBase serverLogic)
|
||||
{
|
||||
return ServerMetricsManager.It.isSetupCompleted();
|
||||
}
|
||||
|
||||
public static async Task<Result> setupDefaultServerMetrics<TRedisConnector>(this IWithServerMetrics serverMetrics, MODULE_ID toRedisConnectorModuleId)
|
||||
where TRedisConnector : RedisConnector
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
var result = new Result();
|
||||
|
||||
var server_logic = serverMetrics as IServerLogic;
|
||||
NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null");
|
||||
|
||||
var found_redis_connector_module = server_logic.getModule(toRedisConnectorModuleId);
|
||||
var casted_redis_connector = found_redis_connector_module as RedisConnector;
|
||||
NullReferenceCheckHelper.throwIfNull(casted_redis_connector, () => $"casted_redis_connector is null - moudleId:{toRedisConnectorModuleId}, moduleType:{typeof(TRedisConnector)} - {server_logic.toBasicString()}");
|
||||
|
||||
return ServerMetricsManager.It.setup(casted_redis_connector);
|
||||
}
|
||||
}
|
||||
33
ServerBase/Helper/TickerHelper.cs
Normal file
33
ServerBase/Helper/TickerHelper.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using ServerCore;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class TickerHelper
|
||||
{
|
||||
public static async Task<Result> createTimeEventForMinuteTicker(this IServerLogic serverLogic)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
// base ticker 등록
|
||||
var entity_ticker_initializers = new Initializers();
|
||||
entity_ticker_initializers.appendInitializer(new TimeEventForMinuteTicker((double)ConstValue.default_1_min_to_sec * ConstValue.default_1_sec_to_milisec, null));
|
||||
|
||||
await entity_ticker_initializers.init("EntityTickers");
|
||||
|
||||
// ticker 등록
|
||||
foreach (var initializer in entity_ticker_initializers.getInitializers())
|
||||
{
|
||||
var entity_ticker = initializer as EntityTicker;
|
||||
NullReferenceCheckHelper.throwIfNull(entity_ticker, () => $"entity_ticker is null !!! - {serverLogic.toBasicString()}");
|
||||
|
||||
result = serverLogic.registerEntityTicker(entity_ticker);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
58
ServerBase/Helper/TransactionRunnerHelper.cs
Normal file
58
ServerBase/Helper/TransactionRunnerHelper.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Amazon.Runtime.Internal;
|
||||
using ServerControlCenter;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
using TRANSACTION_NAME = System.String;
|
||||
using TRANSACTION_GUID = System.String;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public class TransactionRunnerHelper
|
||||
{
|
||||
public static async Task<Result> runTransactionRunnerWithLogic( EntityBase owner
|
||||
, TransactionIdType transactionIdType, TRANSACTION_NAME transactionName
|
||||
, Func<Task<Result>> fnTransactLogic )
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(fnTransactLogic, () => $"fnTransactLogic is null !!! - {owner.toBasicString()}");
|
||||
|
||||
using (var runner = new TransactionRunner(owner, transactionIdType, transactionName))
|
||||
{
|
||||
var result = runner.beginTransaction();
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return await fnTransactLogic.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Result> runTransactionRunnerWithLogic( EntityBase owner, TRANSACTION_GUID transGuid
|
||||
, TransactionIdType transactionIdType, TRANSACTION_NAME transactionName
|
||||
, Func<Task<Result>> fnTransactLogic )
|
||||
{
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
ArgumentNullReferenceCheckHelper.throwIfNull(fnTransactLogic, () => $"fnTransactLogic is null !!! - {owner.toBasicString()}");
|
||||
|
||||
using (var runner = new TransactionRunner(owner, transGuid, transactionIdType, transactionName))
|
||||
{
|
||||
var result = runner.beginTransaction();
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return await fnTransactLogic.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
63
ServerBase/Helper/VersionHelper.cs
Normal file
63
ServerBase/Helper/VersionHelper.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
using Amazon.S3.Model;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
|
||||
namespace ServerBase;
|
||||
|
||||
public static class VersionHelper
|
||||
{
|
||||
public static (Result result, int buildVersion,int revisionVersion) tryReadVersion(string filePath)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var build_version = 0;
|
||||
var revision_version = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
using (var stream = new StreamReader(filePath))
|
||||
{
|
||||
while (stream.Peek() >= 0)
|
||||
{
|
||||
var line = stream.ReadLine();
|
||||
|
||||
if (line == null)
|
||||
break;
|
||||
|
||||
if (line.IndexOf("Build:") >= 0)
|
||||
{
|
||||
var version = line.Replace("Build:", "");
|
||||
build_version = int.Parse(version);
|
||||
}
|
||||
else if (line.IndexOf("Revision:") >= 0)
|
||||
{
|
||||
var version = line.Replace("Revision:", "");
|
||||
revision_version = int.Parse(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var err_msg = $"Exception !!!, Failed to perform in tryReadVersion() !!! : exception:{e} - filePath:{filePath}";
|
||||
result.setFail(ServerErrorCode.TryCatchException, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, 0, 0);
|
||||
}
|
||||
|
||||
return (result, build_version, revision_version);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user