mirror of
https://github.com/stokebob/bnhtrade.git
synced 2026-05-18 19:48:23 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89ec6476fc |
@@ -1,92 +1,78 @@
|
||||
using System;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.Services;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database
|
||||
{
|
||||
/// this class needs a sort out. Ideally it shoud be called what it is, a connection string builder, and
|
||||
/// it should expose a method to serve the connection string--rather than class inheritance and using a property setter
|
||||
/// something to do once there aren't so many open git branches
|
||||
///
|
||||
public class Connection
|
||||
{
|
||||
//protected readonly string SqlConnectionString;
|
||||
private Model.Credentials.bnhtradeDB _dbCredentials;
|
||||
private string _server;
|
||||
private string _user;
|
||||
private string _userPassword;
|
||||
private string _database = "e2A";
|
||||
private bool _persistSecurityInfo = true;
|
||||
private bool _multipleActiveResultSets = true;
|
||||
private bool _encrypt = true;
|
||||
private uint _connectRetryInterval;
|
||||
private uint _connectRetryCount;
|
||||
private uint _connectTimeout;
|
||||
|
||||
protected string SqlConnectionString
|
||||
{
|
||||
get { return _dbCredentials.ConnectionString; }
|
||||
}
|
||||
internal string SqlConnectionString { get; private set; }
|
||||
|
||||
public Connection()
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="connectRetryInterval">Retry interval in seconds, must be 5-60</param>
|
||||
/// <param name="connectTimeout">Timeout length in seconds (0 is indefinitely)</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public Connection(uint connectRetryInterval = 10, uint connectRetryCount = 6, uint connectionTimeout = 60)
|
||||
{
|
||||
if (connectRetryInterval < 5 || connectRetryInterval > 60)
|
||||
{
|
||||
// these are limits set by the sql server
|
||||
throw new ArgumentOutOfRangeException("ConnectRetryInterval must be from 5 to 60 seconds");
|
||||
}
|
||||
_connectRetryInterval = connectRetryInterval;
|
||||
_connectRetryCount = connectRetryCount;
|
||||
_connectTimeout = connectionTimeout;
|
||||
|
||||
// retrive credentials from app.local.config
|
||||
var config = new Config().GetConfiguration();
|
||||
|
||||
// attempt to retrive credentials from app.local.config
|
||||
try
|
||||
{
|
||||
string dataSource = config.AppSettings.Settings["DbDataSource"].Value;
|
||||
string userId = config.AppSettings.Settings["DbUserId"].Value;
|
||||
string pass = config.AppSettings.Settings["DbUserPassword"].Value;
|
||||
_server = config.AppSettings.Settings["DbDataSource"].Value;
|
||||
_user = config.AppSettings.Settings["DbUserId"].Value;
|
||||
_userPassword = config.AppSettings.Settings["DbUserPassword"].Value;
|
||||
|
||||
// check
|
||||
if (string.IsNullOrEmpty(dataSource))
|
||||
if (string.IsNullOrEmpty(_server))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbDataSource' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(userId))
|
||||
else if (string.IsNullOrEmpty(_user))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserId' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(pass))
|
||||
else if (string.IsNullOrEmpty(_userPassword))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserPassword' from config file");
|
||||
}
|
||||
|
||||
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
|
||||
this._dbCredentials = dbCredentials;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Unable to retirve DB credentials: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectionOld()
|
||||
{
|
||||
// attempt to retrive credentials from app.local.config
|
||||
try
|
||||
{
|
||||
string dataSource = ConfigurationManager.AppSettings["DbDataSource"];
|
||||
string userId = ConfigurationManager.AppSettings["DbUserId"];
|
||||
string pass = ConfigurationManager.AppSettings["DbUserPassword"];
|
||||
|
||||
// check
|
||||
if (string.IsNullOrEmpty(dataSource))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbDataSource' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserId' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(pass))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserPassword' from config file");
|
||||
}
|
||||
|
||||
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
|
||||
this._dbCredentials = dbCredentials;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw new Exception("Unable to retirve DB credentials: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public Connection(Model.Credentials.bnhtradeDB dbCredentials)
|
||||
{
|
||||
// setup sql parameters
|
||||
if (dbCredentials == null)
|
||||
{
|
||||
throw new Exception("DB credentials object is null");
|
||||
}
|
||||
this._dbCredentials = dbCredentials;
|
||||
// build connection string
|
||||
SqlConnectionString = "Server=" + _server + ";Database=" + _database + ";PersistSecurityInfo=" + _persistSecurityInfo.ToString()
|
||||
+ ";User=" + _user + ";Password=" + _userPassword + ";MultipleActiveResultSets=" + _multipleActiveResultSets.ToString()
|
||||
+ ";ConnectRetryInterval=" + _connectRetryInterval + ";ConnectRetryCount=" + _connectRetryCount + ";Timeout=" + _connectTimeout
|
||||
+ ";Encrypt=" + _encrypt.ToString() +";";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,6 @@ namespace bnhtrade.Core.Data.Database.Sku.Price
|
||||
{
|
||||
public class ReadParameter : Connection
|
||||
{
|
||||
public ReadParameter() : base()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public List<Model.Sku.Price.SkuRepriceInfo> Execute()
|
||||
{
|
||||
string stringSql = @"
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database
|
||||
{
|
||||
internal class ServerPing
|
||||
{
|
||||
internal ServerPing()
|
||||
{
|
||||
}
|
||||
|
||||
internal Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
/// <summary>
|
||||
/// Polls SQL Server until it comes online, max attempts are reached, or the cancellation token is triggered.
|
||||
/// </summary>
|
||||
/// <param name="timeout">Seconds each connection attempt waits before failing.</param>
|
||||
/// <param name="maxAttempts">Maximum number of poll attempts. 0 = retry indefinitely.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the polling loop.</param>
|
||||
/// <returns>True when the server responds, false if max attempts reached or cancelled.</returns>
|
||||
internal async Task<bool> WaitForServerAsync(uint timeout = 10, uint maxAttempts = 6, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var connection = new Connection(connectionTimeout: timeout);
|
||||
|
||||
int attempt = 0;
|
||||
DateTime firstAttempt = DateTime.UtcNow;
|
||||
int lineWidth = Console.WindowWidth - 1;
|
||||
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Starting to poll SQL Server for availability...");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
attempt++;
|
||||
bool isFinalAttempt = maxAttempts > 0 && attempt >= maxAttempts;
|
||||
|
||||
Console.WriteLine($"\r[{DateTime.Now:HH:mm:ss}] Attempt {attempt} of {maxAttempts} ");
|
||||
|
||||
try
|
||||
{
|
||||
using SqlConnection conn = new SqlConnection(connection.SqlConnectionString);
|
||||
if (attempt == 1)
|
||||
firstAttempt = DateTime.UtcNow;
|
||||
await conn.OpenAsync(cancellationToken);
|
||||
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] SQL Server is online, attempt {attempt} succeeded!");
|
||||
return true;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Console.WriteLine($"\n[{DateTime.Now:HH:mm:ss}] Polling cancelled.");
|
||||
return false;
|
||||
}
|
||||
catch (SqlException ex)
|
||||
{
|
||||
if (isFinalAttempt)
|
||||
{
|
||||
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] SQL Server not available (error {ex.Number}): {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
if (isFinalAttempt)
|
||||
{
|
||||
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Max attempts ({maxAttempts}) reached, could not connect to SQL Server.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// countdown overwrites the same line as the attempt message
|
||||
int retrySeconds = (firstAttempt.AddSeconds(timeout * attempt) - DateTime.UtcNow).Seconds ;
|
||||
for (int i = retrySeconds; i > 0; i--)
|
||||
{
|
||||
Console.Write($"\r[--------] Retrying in {i}s...");
|
||||
try
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Console.WriteLine($"\n[{DateTime.Now:HH:mm:ss}] Polling cancelled.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Configuration;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.UnitOfWork
|
||||
{
|
||||
public class Connection
|
||||
{
|
||||
//protected readonly string SqlConnectionString;
|
||||
private Model.Credentials.bnhtradeDB _dbCredentials;
|
||||
|
||||
protected string SqlConnectionString
|
||||
{
|
||||
get { return _dbCredentials.ConnectionString; }
|
||||
}
|
||||
|
||||
public Connection()
|
||||
{
|
||||
var config = new Config().GetConfiguration();
|
||||
|
||||
// attempt to retrive credentials from app.local.config
|
||||
try
|
||||
{
|
||||
string dataSource = config.AppSettings.Settings["DbDataSource"].Value;
|
||||
string userId = config.AppSettings.Settings["DbUserId"].Value;
|
||||
string pass = config.AppSettings.Settings["DbUserPassword"].Value;
|
||||
|
||||
// check
|
||||
if (string.IsNullOrEmpty(dataSource))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbDataSource' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserId' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(pass))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserPassword' from config file");
|
||||
}
|
||||
|
||||
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
|
||||
this._dbCredentials = dbCredentials;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Unable to retirve DB credentials: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Stock
|
||||
{
|
||||
public class SkuTransactionTypeCrud : Connection // this inheritance can be removed when old code is removed below
|
||||
public class SkuTransactionTypeCrud
|
||||
{
|
||||
private Data.Database.Stock.ReadSkuTransactionType dbRead;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
@@ -14,8 +15,23 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<bool> IsServerOnlineAsync()
|
||||
{
|
||||
using var cts = new CancellationTokenSource();
|
||||
Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cts.Cancel(); };
|
||||
|
||||
return await new bnhtrade.Core.Logic.Utilities.SqlServerPing()
|
||||
.WaitForServerAsync(timeout: 15, maxAttempts: 60, cts.Token);
|
||||
}
|
||||
|
||||
public void DownloadAll()
|
||||
{
|
||||
if (!IsServerOnlineAsync().GetAwaiter().GetResult())
|
||||
{
|
||||
Console.WriteLine("Server is not online, skipping nightly scheduled tasks.");
|
||||
return;
|
||||
}
|
||||
|
||||
log.LogInformation("Nightly scheduled tasks started.");
|
||||
|
||||
bool stockUpdate = false;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Polls SQL Server until it comes online, max attempts are reached, or the operation is cancelled.
|
||||
/// Intended for use on application startup when the remote SQL Server machine may still be booting.
|
||||
/// </summary>
|
||||
public class SqlServerPing
|
||||
{
|
||||
/// <summary>
|
||||
/// Polls SQL Server until it comes online, max attempts are reached, or the cancellation token is triggered.
|
||||
/// </summary>
|
||||
/// <param name="timeout">Seconds each connection attempt waits before failing (1–300).</param>
|
||||
/// <param name="maxAttempts">Maximum number of poll attempts. 0 = retry indefinitely.</param>
|
||||
/// <param name="cancellationToken">Token to cancel the polling loop.</param>
|
||||
/// <returns>True when the server responds, false if max attempts reached or cancelled.</returns>
|
||||
public async Task<bool> WaitForServerAsync(uint timeout = 10, uint maxAttempts = 6, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await new Data.Database.ServerPing().WaitForServerAsync(timeout, maxAttempts, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Credentials
|
||||
{
|
||||
public class AmazonSPAPI
|
||||
{
|
||||
public string AccessKey { get; private set; }
|
||||
public string SecretKey { get; private set; }
|
||||
public string RoleArn { get; private set; }
|
||||
public string ClientId { get; private set; }
|
||||
public string ClientSecret { get; private set; }
|
||||
public string RefreshToken { get; private set; }
|
||||
|
||||
public AmazonSPAPI(string accessKey, string secretKey, string roleArn, string clientId, string clientSecret, string refreshToken)
|
||||
{
|
||||
this.AccessKey = accessKey;
|
||||
this.SecretKey = secretKey;
|
||||
this.RoleArn = roleArn;
|
||||
this.ClientId = clientId;
|
||||
this.ClientSecret = clientSecret;
|
||||
this.RefreshToken = refreshToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Credentials
|
||||
{
|
||||
public class bnhtradeDB
|
||||
{
|
||||
public string DataSource { get; private set; }
|
||||
|
||||
public string UserId { get; private set; }
|
||||
|
||||
public string UserPassword { get; private set; }
|
||||
|
||||
public string InitialCatalog { get; private set; } = "e2A";
|
||||
|
||||
public bool PersistSecurityInfo { get; private set; } = true;
|
||||
|
||||
public bool MultipleActiveResultSets { get; private set; } = true;
|
||||
|
||||
public uint ConnectionTimeout { get; private set; }
|
||||
|
||||
public string ConnectionString
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Data Source=" + DataSource + ";Initial Catalog=" + InitialCatalog + ";Persist Security Info=" + PersistSecurityInfo.ToString()
|
||||
+ ";User ID=" + UserId + ";Password=" + UserPassword + ";MultipleActiveResultSets=" + MultipleActiveResultSets.ToString()
|
||||
+ ";Connect Timeout=" + ConnectionTimeout + ";Encrypt=True";
|
||||
}
|
||||
}
|
||||
|
||||
public bnhtradeDB (string source, string userId, string userPassword, uint connectionTimeout = 30)
|
||||
{
|
||||
this.DataSource = source;
|
||||
this.UserId = userId;
|
||||
this.UserPassword = userPassword;
|
||||
this.ConnectionTimeout = connectionTimeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtradeScheduledTasks
|
||||
@@ -12,7 +13,7 @@ namespace bnhtradeScheduledTasks
|
||||
{
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
@@ -310,7 +311,7 @@ namespace bnhtradeScheduledTasks
|
||||
Console.WriteLine(consoleHeader);
|
||||
Console.WriteLine("Main Menu > Dev Funcions");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("<1> Test some randon function I've set here");
|
||||
Console.WriteLine("<1> Ping SQL Server");
|
||||
Console.WriteLine("<2> Test Account");
|
||||
Console.WriteLine("<3> Test Export");
|
||||
Console.WriteLine("<4> Test Import");
|
||||
@@ -334,7 +335,16 @@ namespace bnhtradeScheduledTasks
|
||||
{
|
||||
Console.Clear();
|
||||
|
||||
var obj = new bnhtrade.Core.Test.Amazon.SP_API.VariousCalls();
|
||||
using var cts = new CancellationTokenSource();
|
||||
Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cts.Cancel(); };
|
||||
|
||||
bool online = await new bnhtrade.Core.Logic.Utilities.SqlServerPing()
|
||||
.WaitForServerAsync(timeout: 10, maxAttempts: 10, cts.Token);
|
||||
|
||||
if (!online)
|
||||
{
|
||||
Console.WriteLine("Could not connect to SQL Server.");
|
||||
}
|
||||
|
||||
Console.WriteLine("Complete, press any key to continue...");
|
||||
Console.ReadKey();
|
||||
|
||||
Reference in New Issue
Block a user