276 lines
9.5 KiB
C#
276 lines
9.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
using Amazon.DynamoDBv2;
|
|
using Amazon.DynamoDBv2.DocumentModel;
|
|
using Amazon.DynamoDBv2.Model;
|
|
using Amazon.Runtime;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
|
|
|
|
using DYNAMO_DB_TABLE_NAME = System.String;
|
|
using DYNAMO_DB_TABLE_FULL_NAME = System.String;
|
|
|
|
|
|
namespace ServerBase;
|
|
|
|
public partial class DynamoDbClient : DynamoDbConnectorBase, IModule, IInitializer
|
|
{
|
|
|
|
public const string TTL_NAME = "TTL";
|
|
public const string SK_EMPTY = "empty";
|
|
public const string PK_GLOBAL = "global";
|
|
|
|
private readonly ModuleContext? m_module_context;
|
|
|
|
|
|
public DynamoDbClient()
|
|
: base()
|
|
{ }
|
|
|
|
public DynamoDbClient(ModuleContext moduleContext)
|
|
: base()
|
|
{
|
|
m_module_context = moduleContext;
|
|
}
|
|
|
|
public async Task<Result> onInit()
|
|
{
|
|
var err_msg = string.Empty;
|
|
var result = new Result();
|
|
|
|
var module_context = getModuleContext();
|
|
var config_param = module_context.getConfigParam() as ConfigParam;
|
|
NullReferenceCheckHelper.throwIfNull(config_param, () => $"config_param is null !!!");
|
|
|
|
result = connectToDb(config_param);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to create DB Table !!! - {toBasicString()}";
|
|
Log.getLogger().fatal(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
|
|
if (false == await createDBIfNotExists(false))
|
|
{
|
|
err_msg = $"Failed to createDBIfNotExists() !!! - {toBasicString()}";
|
|
result.setFail(ServerErrorCode.DynamoDbTableCreateFailed, err_msg);
|
|
Log.getLogger().fatal(result.toBasicString());
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> startModule()
|
|
{
|
|
var result = new Result();
|
|
return await Task.FromResult(result);
|
|
}
|
|
|
|
public async Task<Result> stopModule()
|
|
{
|
|
var result = new Result();
|
|
return await Task.FromResult(result);
|
|
}
|
|
|
|
public Result connectToDb(ConfigParam configParam)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
(var error_code, var to_load_table_names) = ServerConfigHelper.getDynamoDbTableNamesWithServiceType(configParam.ServiceType);
|
|
if (error_code.isFail())
|
|
{
|
|
err_msg = $"Failed to DynamoDbClient.getDynamoDbTableNameWithServiceType() !!! : {configParam.toBasicString()} - {toBasicString()}";
|
|
result.setFail(error_code, err_msg);
|
|
Log.getLogger().error(err_msg);
|
|
|
|
return result;
|
|
}
|
|
|
|
return connectToDb( to_load_table_names
|
|
, configParam.IsLocalDynamoDB, configParam.UrlOfDynamoDb
|
|
, configParam.AccessKeyOfAws, configParam.SecretKeyOfAws, configParam.RegionOfAws );
|
|
}
|
|
|
|
public Result connectToDb( ConcurrentDictionary<DYNAMO_DB_TABLE_NAME, DYNAMO_DB_TABLE_FULL_NAME> tableNames, bool localDynamoDb
|
|
, string dynamodbUrl
|
|
, string awsAccessKey, string awsSecretKey
|
|
, string awsRegion = "" )
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
foreach( var each in tableNames )
|
|
{
|
|
var table_name = each.Key;
|
|
var table_full_name = each.Value;
|
|
|
|
if(false == addTableFullName(table_name, table_full_name))
|
|
{
|
|
err_msg = $"Failed to addTableFullName() !!! : tableName:{table_name}, tableFullName:{table_full_name} - {toBasicString()}";
|
|
result.setFail(ServerErrorCode.DynamoDbTableNameDuplicated, err_msg);
|
|
Log.getLogger().fatal(result.toBasicString());
|
|
return result;
|
|
}
|
|
}
|
|
|
|
var db_config = new AmazonDynamoDBConfig();
|
|
db_config.BufferSize = 4 * 1024 * 1024; // 4 MB
|
|
db_config.RetryMode = RequestRetryMode.Standard;
|
|
db_config.DisableLogging = false; // Logging is disabled by default. - Set to true to enable request-level logging.
|
|
db_config.ThrottleRetries = false; // Throttled requests are not automatically retried. - Set to false to automatically retry throttled requests.
|
|
|
|
if (localDynamoDb)
|
|
{
|
|
// DynamoDB-Local is running, so create a client
|
|
Log.getLogger().info($"Setting up a DynamoDB-Local client (DynamoDB Local seems to be running)");
|
|
|
|
db_config.ServiceURL = dynamodbUrl;
|
|
|
|
if (false == base.connectToDb(awsAccessKey, awsSecretKey, db_config))
|
|
{
|
|
err_msg = $"Failed to connect a DynamoDB-Local client !!! : {toBasicString()}";
|
|
result.setFail(ServerErrorCode.DynamoDbConnectFailed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Log.getLogger().info($"Setting up a DynamoDB-Remote client : TargetRegion:{awsRegion}");
|
|
|
|
try
|
|
{
|
|
db_config.RegionEndpoint = Amazon.RegionEndpoint.GetBySystemName(awsRegion);
|
|
|
|
if (false == base.connectToDb(awsAccessKey, awsSecretKey, db_config))
|
|
{
|
|
err_msg = $"Failed to connect a DynamoDB-Remote client !!! : {toBasicString()}";
|
|
result.setFail(ServerErrorCode.DynamoDbConnectFailed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
err_msg = $"Failed to connect a DynamoDB-Remote client !!! : Exception:{e}, {toBasicString()}";
|
|
result.setFail(ServerErrorCode.DynamoDbConnectFailed, err_msg);
|
|
Log.getLogger().fatal(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public Result connectToDb( string tableName, bool localDynamoDB, string dynamodbUrl
|
|
, string awsAccessKey, string awsSecretKey, string awsRegion = "")
|
|
{
|
|
var table_names = new ConcurrentDictionary<DYNAMO_DB_TABLE_NAME, DYNAMO_DB_TABLE_FULL_NAME>();
|
|
table_names[tableName] = tableName;
|
|
|
|
return connectToDb( table_names, localDynamoDB, dynamodbUrl
|
|
, awsAccessKey, awsSecretKey, awsRegion );
|
|
}
|
|
|
|
public async Task<bool> createDBIfNotExists(bool resetTable)
|
|
{
|
|
var err_msg = string.Empty;
|
|
|
|
var db_client = getDbClient();
|
|
if (db_client == null)
|
|
{
|
|
err_msg = $"Not created DynamoDbClient !!! - {toBasicString()}";
|
|
Log.getLogger().fatal(err_msg);
|
|
return false;
|
|
}
|
|
|
|
var loaded_table_full_names = getTableNames().Values.ToList();
|
|
|
|
if (resetTable == true)
|
|
{
|
|
if(false == await deleteTables(loaded_table_full_names))
|
|
{
|
|
err_msg = $"Failed to DynamoDbClient.deleteTables() !!! - {toBasicString()}";
|
|
Log.getLogger().fatal(err_msg);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
List<AttributeDefinition> tableAttributes = new List<AttributeDefinition>();
|
|
tableAttributes.Add(new AttributeDefinition(PrimaryKey.PK_Define, ScalarAttributeType.S));
|
|
tableAttributes.Add(new AttributeDefinition(PrimaryKey.SK_Define, ScalarAttributeType.S));
|
|
|
|
List<KeySchemaElement> tableKeySchema = new List<KeySchemaElement>();
|
|
tableKeySchema.Add(new KeySchemaElement(PrimaryKey.PK_Define, KeyType.HASH));
|
|
tableKeySchema.Add(new KeySchemaElement(PrimaryKey.SK_Define, KeyType.RANGE));
|
|
|
|
foreach (var table_full_name in loaded_table_full_names)
|
|
{
|
|
if (await isExistTable(table_full_name) == false)
|
|
{
|
|
var ttl_update = new UpdateTimeToLiveRequest
|
|
{
|
|
TableName = table_full_name,
|
|
TimeToLiveSpecification = new TimeToLiveSpecification
|
|
{
|
|
AttributeName = TTL_NAME, // TTL로 사용할 속성 이름
|
|
Enabled = true // TTL 사용 여부
|
|
}
|
|
};
|
|
if(false == await createTable( db_client, table_full_name, ttl_update
|
|
, tableAttributes, tableKeySchema ))
|
|
{
|
|
err_msg = $"Failed to DynamoDbClient.addTable() !!! - {toBasicString()}";
|
|
Log.getLogger().fatal(err_msg);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if(false == addTable(table_full_name, Table.LoadTable(db_client, table_full_name)))
|
|
{
|
|
err_msg = $"Failed to DynamoDbClient.addTable() !!! : tableName:{table_full_name} - {toBasicString()}";
|
|
Log.getLogger().fatal(err_msg);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
DynamoDbQueryOperationOptionConfig.configure();
|
|
|
|
return true;
|
|
}
|
|
|
|
public Table getTableByDoc<TDoc>()
|
|
where TDoc : DynamoDbDocBase, new()
|
|
{
|
|
return getTableByName((new TDoc()).TableName);
|
|
}
|
|
|
|
public Table getTableByDoc<TDoc>(TDoc doc)
|
|
where TDoc : DynamoDbDocBase
|
|
{
|
|
return getTableByName(doc.TableName);
|
|
}
|
|
|
|
public ModuleContext getModuleContext()
|
|
{
|
|
NullReferenceCheckHelper.throwIfNull(m_module_context, () => $"m_module_context is null !!!");
|
|
return m_module_context;
|
|
}
|
|
}
|