1082 lines
37 KiB
C#
1082 lines
37 KiB
C#
using NLog;
|
|
using RestSharp;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Configuration;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.NetworkInformation;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace IOB_UT_NEXT
|
|
{
|
|
public class baseUtils
|
|
{
|
|
#region Public Fields
|
|
|
|
/// <summary>
|
|
/// Indicazione VETO PING a server sino alla data-ora indicata
|
|
/// </summary>
|
|
public static DateTime dtVetoPing = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// Indicazione VETO accodamento INGRESSI/EVENTI sino alla data-ora indicata
|
|
/// </summary>
|
|
public static DateTime dtVetoQueueIN = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// Indicazione VETO invio a server sino alla data-ora indicata
|
|
/// </summary>
|
|
public static DateTime dtVetoSend = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// Status IOB
|
|
/// </summary>
|
|
public static bool IOB_Online = false;
|
|
|
|
/// <summary>
|
|
/// Status MP_IO
|
|
/// </summary>
|
|
public static bool MPIO_Online = false;
|
|
|
|
#endregion Public Fields
|
|
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// Calcola una pausa con errore casuale x il prossimo send programmato verso SERVER
|
|
/// </summary>
|
|
public static int nextPauseSendMSec
|
|
{
|
|
get
|
|
{
|
|
// parto dal dato std di veto per pauseSendMSec
|
|
int answ = CRI("pauseSendMSec");
|
|
// aggiungo NOISE... +/- 50%
|
|
Random rnd = new Random();
|
|
int noise = rnd.Next(1, answ / 2);
|
|
answ += noise - (answ / 4);
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// formatta un numero in forma binaria 0/1
|
|
/// </summary>
|
|
/// <param name="valore"></param>
|
|
/// <returns></returns>
|
|
public static string binaryForm(int valore)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(new BinaryUtils(), "{0:B}", valore);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// formatta un numero in forma binaria 0/1
|
|
/// </summary>
|
|
/// <param name="valore"></param>
|
|
/// <returns></returns>
|
|
public static string binaryForm(uint valore)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
answ = string.Format(new BinaryUtils(), "{0:B}", valore);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata URL tramite RestSharp e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
|
|
/// </summary>
|
|
/// <param name="url">URI da chiamare</param>
|
|
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
|
|
/// <returns></returns>
|
|
public static string ExecCallGet(string url, bool fastCall = false)
|
|
{
|
|
string answ = "";
|
|
// divido url tra base e opzionale...
|
|
Uri uri = new Uri(url);
|
|
string baseUrl = $"{uri.Scheme}://{uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}";
|
|
string resource = uri.AbsolutePath;
|
|
RestClientOptions restOptStd = new RestClientOptions
|
|
{
|
|
BaseUrl = new Uri(baseUrl),
|
|
Timeout = TimeSpan.FromSeconds(60)
|
|
};
|
|
if (!string.IsNullOrEmpty(url))
|
|
{
|
|
if (fastCall)
|
|
{
|
|
restOptStd.Timeout = TimeSpan.FromSeconds(5);
|
|
}
|
|
try
|
|
{
|
|
// client chiamate rest
|
|
using (var client = new RestClient(restOptStd))
|
|
{
|
|
var actReq = new RestRequest(resource, Method.Get);
|
|
// effettuo vera chiamata
|
|
var currResp = client.Get(actReq);
|
|
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
|
|
{
|
|
answ = currResp.Content ?? "";
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in callRestUrl{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata URL tramite RestSharp e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
|
|
/// </summary>
|
|
/// <param name="url">URI da chiamare</param>
|
|
/// <param name="payload">Payload da allegare (già serializzato)</param>
|
|
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
|
|
/// <returns></returns>
|
|
public static string ExecCallPostJson(string url, string payload, bool fastCall = false)
|
|
{
|
|
string answ = "";
|
|
// divido url tra base e opzionale...
|
|
Uri uri = new Uri(url);
|
|
string baseUrl = $"{uri.Scheme}://{uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}";
|
|
string resource = uri.AbsolutePath;
|
|
RestClientOptions restOptStd = new RestClientOptions
|
|
{
|
|
BaseUrl = new Uri(baseUrl),
|
|
Timeout = TimeSpan.FromSeconds(60)
|
|
};
|
|
if (!string.IsNullOrEmpty(url))
|
|
{
|
|
if (fastCall)
|
|
{
|
|
restOptStd.Timeout = TimeSpan.FromSeconds(5);
|
|
}
|
|
try
|
|
{
|
|
// client chiamate rest
|
|
using (var client = new RestClient(restOptStd))
|
|
{
|
|
var actReq = new RestRequest(resource, Method.Post);
|
|
actReq.AddJsonBody(payload);
|
|
// effettuo vera chiamata
|
|
var currResp = client.Post(actReq);
|
|
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
|
|
{
|
|
answ = currResp.Content ?? "";
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in callRestUrlJson{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata URL tramite RestSharp e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
|
|
/// </summary>
|
|
/// <param name="url">URI da chiamare</param>
|
|
/// <param name="payload">Payload da allegare (già serializzato)</param>
|
|
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
|
|
/// <returns></returns>
|
|
public static string ExecCallPostPlain(string url, string payload, bool fastCall = false)
|
|
{
|
|
string answ = "";
|
|
// divido url tra base e opzionale...
|
|
Uri uri = new Uri(url);
|
|
string baseUrl = $"{uri.Scheme}://{uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}";
|
|
string resource = uri.AbsolutePath;
|
|
RestClientOptions restOptStd = new RestClientOptions
|
|
{
|
|
BaseUrl = new Uri(baseUrl),
|
|
Timeout = TimeSpan.FromSeconds(60)
|
|
};
|
|
if (!string.IsNullOrEmpty(url))
|
|
{
|
|
if (fastCall)
|
|
{
|
|
restOptStd.Timeout = TimeSpan.FromSeconds(5);
|
|
}
|
|
try
|
|
{
|
|
// client chiamate rest
|
|
using (var client = new RestClient(restOptStd))
|
|
{
|
|
var actReq = new RestRequest(resource, Method.Post);
|
|
actReq.AddStringBody(payload, ContentType.Plain);
|
|
// effettuo vera chiamata
|
|
var currResp = client.Post(actReq);
|
|
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
|
|
{
|
|
answ = currResp.Content ?? "";
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Error($"Eccezione in callRestUrlJson{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata URL e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
|
|
/// </summary>
|
|
/// <param name="URL"></param>
|
|
/// <returns></returns>
|
|
public static string callUrl(string URL)
|
|
{
|
|
string answ = "";
|
|
// controllo se ho un VETO all'invio...
|
|
if (dtVetoSend < DateTime.Now)
|
|
{
|
|
answ = callUrlNow(URL);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata URL e restituisce risultato
|
|
/// </summary>
|
|
/// <param name="URL"></param>
|
|
/// <param name="payload"></param>
|
|
/// <returns></returns>
|
|
public static string callUrl(string URL, string payload)
|
|
{
|
|
string answ = "";
|
|
// controllo se ho un VETO all'invio...
|
|
if (dtVetoSend < DateTime.Now)
|
|
{
|
|
answ = callUrlNow(URL, payload);
|
|
}
|
|
// restituisco valore!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Client HTTP statico e riutilizzabile per tutto il ciclo di vita dell'app
|
|
/// </summary>
|
|
private static readonly HttpClient _httpClient = new HttpClient();
|
|
|
|
/// <summary>
|
|
/// Metodo chiamata URL con POST async
|
|
/// </summary>
|
|
/// <param name="URL"></param>
|
|
/// <param name="payload"></param>
|
|
/// <param name="ct"></param>
|
|
/// <returns></returns>
|
|
public static async Task<string> callUrlAsync(string URL, string payload, CancellationToken ct = default)
|
|
{
|
|
try
|
|
{
|
|
// Se hai un payload, probabilmente è una POST
|
|
var content = new StringContent(payload, Encoding.UTF8, "application/json");
|
|
|
|
// Qui il thread viene RILASCIATO. La CPU dell'istanza va a 0%
|
|
// mentre aspetta la risposta dal server.
|
|
HttpResponseMessage response = await _httpClient.PostAsync(URL, content, ct);
|
|
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
return await response.Content.ReadAsStringAsync();
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
// Gestisci la cancellazione (quando chiudi l'app o scade il timeout)
|
|
return "Canceled";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Gestisci errori di rete
|
|
return $"Error: {ex.Message}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo chiamata URL con GET async
|
|
/// </summary>
|
|
/// <param name="URL"></param>
|
|
/// <param name="ct"></param>
|
|
/// <returns></returns>
|
|
public static async Task<string> callUrlAsync(string URL,CancellationToken ct = default)
|
|
{
|
|
try
|
|
{
|
|
|
|
// Qui il thread viene RILASCIATO. La CPU dell'istanza va a 0%
|
|
// mentre aspetta la risposta dal server.
|
|
HttpResponseMessage response = await _httpClient.GetAsync(URL, ct);
|
|
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
return await response.Content.ReadAsStringAsync();
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
// Gestisci la cancellazione (quando chiudi l'app o scade il timeout)
|
|
return "Canceled";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Gestisci errori di rete
|
|
return $"Error: {ex.Message}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata URL IMMEDIATAMENTE e restituisce risultato
|
|
/// </summary>
|
|
/// <param name="URL"></param>
|
|
/// <returns></returns>
|
|
public static string callUrlNow(string URL)
|
|
{
|
|
string answ = "";
|
|
if (client == null)
|
|
{
|
|
client = new WebClientWT();
|
|
}
|
|
client.Headers.Add("user-agent", $"{CRS("appName")}");
|
|
try
|
|
{
|
|
// problema certificati locali...
|
|
// https://living-sun.com/it/c/226351-webexception-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel-c-aspnet-web-services-ssl-webexception.html
|
|
// hack x certificati locali in 10.74.82.*
|
|
if (URL.Contains("10.74.82."))
|
|
{
|
|
System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
|
|
}
|
|
answ = client.DownloadString(URL);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
// imposto veto
|
|
int pauseSendMSec = nextPauseSendMSec;
|
|
dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec);
|
|
|
|
// controllo log permesso...
|
|
if (logValuePermit(URL))
|
|
{
|
|
lg.Error($"Errore in callURL verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata{Environment.NewLine}Eccezione:{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
// restituisco valore!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua chiamata IMMEDIATAMENTE URL e restituisce risultato
|
|
/// </summary>
|
|
/// <param name="URL"></param>
|
|
/// <param name="payload"></param>
|
|
/// <returns></returns>
|
|
public static string callUrlNow(string URL, string payload)
|
|
{
|
|
string answ = "";
|
|
if (clientPayload == null)
|
|
{
|
|
clientPayload = new WebClientWT();
|
|
}
|
|
clientPayload.Headers.Add("user-agent", $"{CRS("appName")}-PAYLOAD");
|
|
clientPayload.Headers.Add("Content-Type", "application/json");
|
|
try
|
|
{
|
|
// problema certificati locali...
|
|
// https://living-sun.com/it/c/226351-webexception-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel-c-aspnet-web-services-ssl-webexception.html
|
|
// hack x certificati locali in 10.74.*
|
|
if (URL.Contains("10.74."))
|
|
{
|
|
System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
|
|
}
|
|
answ = clientPayload.UploadString(URL, payload);
|
|
if (answ != "OK")
|
|
{
|
|
// controllo log permesso...
|
|
if (logValuePermit($"{URL}|[{answ}]"))
|
|
{
|
|
lg.Error($"Invio dati fallito, ricevuto messaggio [{answ}]:{Environment.NewLine}- URL{Environment.NewLine}{URL}{Environment.NewLine}- payload{Environment.NewLine}{payload}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
// imposto veto
|
|
int pauseSendMSec = nextPauseSendMSec;
|
|
dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec);
|
|
// controllo log permesso...
|
|
if (logValuePermit(URL))
|
|
{
|
|
lg.Error($"Errore in callURL con PAYLOAD verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata. Dump Payload:{Environment.NewLine}{payload}{Environment.NewLine}Eccezione:{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
// restituisco valore!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test esistenza/creazione directory
|
|
/// </summary>
|
|
/// <param name="dirPath"></param>
|
|
public static void checkDir(string dirPath)
|
|
{
|
|
if (!Directory.Exists(dirPath))
|
|
{
|
|
lg.Info($"Dir not found: {dirPath}");
|
|
Directory.CreateDirectory(dirPath);
|
|
lg.Info($"reated local dir {dirPath}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Conteggio valori true in un array di boolean
|
|
/// </summary>
|
|
/// <param name="args"></param>
|
|
/// <returns></returns>
|
|
public static int CountTrue(params bool[] args)
|
|
{
|
|
return args.Count(t => t);
|
|
}
|
|
|
|
/// <summary>
|
|
/// legge conf in formato BOOLean
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public static bool CRB(string key)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
answ = Convert.ToBoolean(CRS(key));
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// legge conf in formato char
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public static char CRC(string key)
|
|
{
|
|
char answ = '-';
|
|
try
|
|
{
|
|
answ = ConfigurationManager.AppSettings[key].ToCharArray()[0];
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// legge conf in formato INT
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public static Int32 CRI(string key)
|
|
{
|
|
int answ = 0;
|
|
try
|
|
{
|
|
answ = Convert.ToInt32(CRS(key));
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// legge conf in formato stringa
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <returns></returns>
|
|
public static string CRS(string key)
|
|
{
|
|
return ConfigurationManager.AppSettings[key] ?? string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcolo MD5 del fine indicato
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public static string GetFileMd5(string fileName)
|
|
{
|
|
string answ = "";
|
|
using (var md5 = MD5.Create())
|
|
{
|
|
using (var stream = File.OpenRead(fileName))
|
|
{
|
|
var hash = md5.ComputeHash(stream);
|
|
answ = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce la prima cifra (a sx) da un numero (es x decodere quale memoria modbus sia)
|
|
/// </summary>
|
|
/// <param name="num">Numero di cui trovare la priam cifra</param>
|
|
/// <returns></returns>
|
|
public static int getFirstInt(int num)
|
|
{
|
|
if (num >= 100000000) num /= 100000000;
|
|
if (num >= 10000) num /= 10000;
|
|
if (num >= 100) num /= 100;
|
|
if (num >= 10) num /= 10;
|
|
|
|
#if false
|
|
// formulazione alternativa con ciclo...
|
|
while (num >= 10)
|
|
num /= 10;
|
|
#endif
|
|
|
|
return num;
|
|
}
|
|
|
|
/// <summary>
|
|
/// IP della macchina
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string GetIP()
|
|
{
|
|
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
|
|
String sIpAddr = string.Empty;
|
|
try
|
|
{
|
|
foreach (NetworkInterface adapter in nics)
|
|
{
|
|
if (sIpAddr == String.Empty)// only return IP Address from first card
|
|
{
|
|
IPInterfaceProperties properties = adapter.GetIPProperties();
|
|
foreach (var item in properties.UnicastAddresses)
|
|
{
|
|
if (item.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
|
{
|
|
sIpAddr = item.Address.ToString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
// controllo log permesso...
|
|
if (logValuePermit("GetIP"))
|
|
{
|
|
lg.Error(exc);
|
|
}
|
|
}
|
|
return sIpAddr;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Macaddress della macchina
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string GetMACAddress()
|
|
{
|
|
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
|
|
String sMacAddress = string.Empty;
|
|
foreach (NetworkInterface adapter in nics)
|
|
{
|
|
if (sMacAddress == String.Empty)// only return MAC Address from first card
|
|
{
|
|
IPInterfaceProperties properties = adapter.GetIPProperties();
|
|
//sMacAddress = adapter.GetPhysicalAddress().ToString();
|
|
sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray());
|
|
}
|
|
}
|
|
return sMacAddress;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce una stringa di soli caratteri numerici (stripe caratteri alfabetici)
|
|
/// </summary>
|
|
/// <param name="input"></param>
|
|
/// <returns></returns>
|
|
public static string GetNumbers(string input)
|
|
{
|
|
return new string(input.Where(c => char.IsDigit(c)).ToArray());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method to convert an integer to a string containing the number in binary. A negative
|
|
/// number will be formatted as a 32-character binary number in two's compliment.
|
|
/// </summary>
|
|
/// <param name="theNumber">self-explanatory</param>
|
|
/// <param name="minimumDigits">
|
|
/// if binary number contains fewer characters leading zeros are added
|
|
/// </param>
|
|
/// <returns>string as described above</returns>
|
|
public static string IntToBinStr(int theNumber, int minimumDigits)
|
|
{
|
|
return Convert.ToString(theNumber, 2).PadLeft(minimumDigits, '0');
|
|
}
|
|
|
|
/// <summary>
|
|
/// verifica se un dato bit sia alzato (come flag di strobe)
|
|
/// </summary>
|
|
/// <param name="value">valore da testare</param>
|
|
/// <param name="flag">
|
|
/// valore cercato, può essere un singolo valore o un insieme in modalità AND
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public static bool IsSetAll(StFlag32 value, StFlag32 flag)
|
|
{
|
|
return ((value & flag) == flag);
|
|
}
|
|
|
|
/// <summary>
|
|
/// verifica se un dato bit sia alzato (come flag di strobe)
|
|
/// </summary>
|
|
/// <param name="value">valore da testare</param>
|
|
/// <param name="flag">
|
|
/// valore cercato, può essere un singolo valore o un insieme in modalità OR
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public static bool IsSetAny(StFlag32 value, StFlag32 flag)
|
|
{
|
|
return ((value & flag) != 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test ping x indirizzo indicato
|
|
/// </summary>
|
|
/// <param name="address"></param>
|
|
/// <returns></returns>
|
|
public static bool pingAddress(IPAddress address)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
Ping pingSender = new Ping();
|
|
PingReply reply = pingSender.Send(address, 100);
|
|
// se passa il ping do OK...
|
|
if (reply.Status == IPStatus.Success)
|
|
{
|
|
answ = true;
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
// controllo log permesso...
|
|
if (logValuePermit("pingAddr"))
|
|
{
|
|
lg.Error(exc);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lettura dictionary da file
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> ReadBin(string file)
|
|
{
|
|
var result = new Dictionary<string, string>();
|
|
// verifico file esista...
|
|
if (!File.Exists(file))
|
|
{
|
|
FileStream fs = File.Create(file);
|
|
fs.Close();
|
|
}
|
|
using (FileStream fs = File.OpenRead(file))
|
|
using (BinaryReader reader = new BinaryReader(fs))
|
|
{
|
|
// Get count.
|
|
int count = 0;
|
|
try
|
|
{
|
|
count = reader.ReadInt32();
|
|
}
|
|
catch
|
|
{ }
|
|
// Read in all pairs.
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
string key = reader.ReadString();
|
|
string value = reader.ReadString();
|
|
result[key] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lettura dictionary da file
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <returns></returns>
|
|
public static Dictionary<string, string> ReadPlain(string file)
|
|
{
|
|
// inizializzo num righe lette...
|
|
int numRow = 0;
|
|
var result = new Dictionary<string, string>();
|
|
// verifico file esista...
|
|
if (!File.Exists(file))
|
|
{
|
|
FileStream fs = File.Create(file);
|
|
fs.Close();
|
|
}
|
|
try
|
|
{
|
|
string[] lines = File.ReadAllLines(file);
|
|
result = lines.Select(l => l.Split(':')).ToDictionary(a => a[0], a => a[1]);
|
|
numRow = result.Count;
|
|
}
|
|
catch
|
|
{ }
|
|
// se leggesse un valore NON coerente (senza righe) restituisce un file vuoto...
|
|
if (numRow == 0)
|
|
{
|
|
result = new Dictionary<string, string>();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static void resetWebClients()
|
|
{
|
|
// resetto i webclients...
|
|
client = new WebClientWT();
|
|
clientPayload = new WebClientWT();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua reverse della stringa
|
|
/// </summary>
|
|
/// <param name="s"></param>
|
|
/// <returns></returns>
|
|
public static string reverseStr(string s)
|
|
{
|
|
char[] arr = s.ToCharArray();
|
|
Array.Reverse(arr);
|
|
return new string(arr);
|
|
}
|
|
|
|
/// <summary>
|
|
/// imposta un bit al valore richiesto duplicando il valore IN come OUT
|
|
/// </summary>
|
|
/// <param name="original">valore originale da aggiornare</param>
|
|
/// <param name="bitBool">valore richiesto x il bit (0/1)</param>
|
|
/// <param name="bitIndex">indice bit, 0 based (es: 0..31 per 32bit)</param>
|
|
/// <returns></returns>
|
|
public static byte[] setBitOnStFlag(byte[] original, bool bitBool, int bitIndex)
|
|
{
|
|
int bitVal = 0;
|
|
if (bitBool)
|
|
{
|
|
bitVal = 1;
|
|
}
|
|
// risposta è identica ad originale...
|
|
byte[] answ = original;
|
|
// verifico se il bit è 0/1b
|
|
if (bitVal <= 1 && bitVal >= 0)
|
|
{
|
|
// verifico se si possa aggiornare il bit richiesto (<= al totale dei bit...)
|
|
if (bitIndex <= original.Length * 8 - 1)
|
|
{
|
|
// calcolo byte
|
|
int byteIndex = bitIndex / 8;
|
|
// bit nel byte
|
|
int bitInByteIndex = bitIndex % 8;
|
|
// bit richiesto
|
|
byte mask = (byte)(bitVal << bitInByteIndex);
|
|
// imposto!
|
|
answ[byteIndex] |= mask;
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// provvede a verificare la dim della cartella dei log e cancella i + vecchi fino a restare
|
|
/// a dim inferiori a _logMaxMb
|
|
/// </summary>
|
|
public static void shrinkDir(string dirPath)
|
|
{
|
|
// obj filemover...
|
|
fileMover.obj.setDirectory(dirPath);
|
|
float dirSizeMb = fileMover.obj.totalMb();
|
|
lg.Info("Inizio shrinkDir LOG folder: {0} Mb", dirSizeMb);
|
|
|
|
// ottengo elenco files *.txt
|
|
FileInfo[] _fis = fileMover.obj.elencoFiles_FI("*.log");
|
|
int numDdMax = 2;
|
|
try
|
|
{
|
|
numDdMax = CRI("zipLogOldDay");
|
|
}
|
|
catch
|
|
{ }
|
|
foreach (FileInfo _file in _fis)
|
|
{
|
|
if (_file.LastWriteTime < DateTime.Now.AddDays(-1)) // zippo files + vecchi di 2 gg...
|
|
{
|
|
fileMover.obj.zippaSingoloFile(_file);
|
|
// cancello l'originale...
|
|
fileMover.obj.eliminaFile(_file);
|
|
}
|
|
}
|
|
// inizio con eliminare file + vecchi della data indicata...
|
|
int maxLogDays = CRI("maxLogDays");
|
|
fileMover.obj.deleteOlderThan(maxLogDays);
|
|
// ora controllo SE sia superata la dim max della directory --> in tal caso cancello dal
|
|
// + vecchio...
|
|
dirSizeMb = fileMover.obj.totalMb();
|
|
int maxLogDirSize = CRI("maxLogDirSize");
|
|
int maxTry = 100;
|
|
// controllo se serva eliminare...
|
|
if (dirSizeMb > maxLogDirSize)
|
|
{
|
|
lg.Info("Continuo shrinkDir LOG folder: {0} Mb --> ELIMINAZIONE FILES", dirSizeMb);
|
|
while (dirSizeMb > maxLogDirSize)
|
|
{
|
|
fileMover.obj.deleteOldest();
|
|
maxTry--;
|
|
if (maxTry > 0)
|
|
{
|
|
dirSizeMb = fileMover.obj.totalMb();
|
|
}
|
|
else
|
|
{
|
|
// per uscire fingo di aver ridotto...
|
|
dirSizeMb = maxLogDirSize - 1;
|
|
}
|
|
}
|
|
dirSizeMb = fileMover.obj.totalMb();
|
|
lg.Info("Completata shrinkDir LOG folder: {0} Mb", dirSizeMb);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restitusice la stringa prima dell'ultima occorrenza del char richiesto
|
|
/// </summary>
|
|
/// <param name="origString">string originale</param>
|
|
/// <param name="sepChar">char separatore da cercare</param>
|
|
/// <returns></returns>
|
|
public static string StringBeforeLastChar(string origString, char sepChar)
|
|
{
|
|
int index = origString.LastIndexOf(sepChar);
|
|
string answ = (index == -1) ? origString : origString.Substring(0, index);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converte un bitarray a byte[]
|
|
/// </summary>
|
|
/// <param name="bits"></param>
|
|
/// <returns></returns>
|
|
public static byte[] ToByteArray(BitArray bits)
|
|
{
|
|
int numBytes = bits.Count / 8;
|
|
if (bits.Count % 8 != 0)
|
|
{
|
|
numBytes++;
|
|
}
|
|
|
|
byte[] bytes = new byte[numBytes];
|
|
int byteIndex = 0, bitIndex = 0;
|
|
|
|
for (int i = 0; i < bits.Count; i++)
|
|
{
|
|
if (bits[i])
|
|
{
|
|
bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
|
|
}
|
|
|
|
bitIndex++;
|
|
if (bitIndex == 8)
|
|
{
|
|
bitIndex = 0;
|
|
byteIndex++;
|
|
}
|
|
}
|
|
|
|
return bytes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scrittura dictionary su file
|
|
/// </summary>
|
|
/// <param name="dictionary"></param>
|
|
/// <param name="file"></param>
|
|
public static void WriteBin(Dictionary<string, string> dictionary, string file)
|
|
{
|
|
using (FileStream fs = File.OpenWrite(file))
|
|
using (BinaryWriter writer = new BinaryWriter(fs))
|
|
{
|
|
// Put count.
|
|
writer.Write(dictionary.Count);
|
|
// Write pairs.
|
|
foreach (var pair in dictionary)
|
|
{
|
|
writer.Write(pair.Key);
|
|
writer.Write(pair.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scrittura dictionary su file
|
|
/// </summary>
|
|
/// <param name="dictionary"></param>
|
|
/// <param name="file"></param>
|
|
public static void WritePlain(Dictionary<string, string> dictionary, string file)
|
|
{
|
|
string dirPath = file.Substring(0, file.LastIndexOf('\\'));
|
|
// verifico directory
|
|
checkDir(dirPath);
|
|
string[] lines = dictionary.OrderBy(i => i.Key).Select(kvp => kvp.Key + ":" + kvp.Value).ToArray();
|
|
//string[] lines = dictionary.OrderBy(i => i.Key).Select(kvp => kvp.Key + ":" + kvp.Value).ToArray();
|
|
try
|
|
{
|
|
File.WriteAllLines(file, lines);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lg.Info(exc, string.Format("Errore in scrittura file {0}", file));
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// Classe logger
|
|
/// </summary>
|
|
protected static Logger lg = LogManager.GetCurrentClassLogger();
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Properties
|
|
|
|
/// <summary>
|
|
/// Oggetto WebClient BASE da riutilizzare
|
|
/// </summary>
|
|
protected static WebClientWT client { get; set; }
|
|
|
|
/// <summary>
|
|
/// Oggetto WebClient con PAYLOAD da riutilizzare
|
|
/// </summary>
|
|
protected static WebClientWT clientPayload { get; set; }
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Private Fields
|
|
|
|
/// <summary>
|
|
/// Dizionario dei valori bloccati x evitare log eccessivo
|
|
/// </summary>
|
|
private static Dictionary<string, DateTime> vetoLogError = new Dictionary<string, DateTime>();
|
|
|
|
/// <summary>
|
|
/// Periodo di veto log in minuti
|
|
/// </summary>
|
|
private static int vetoPeriodMin = 30;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Verifica se il log di un dato errore sia permesso
|
|
/// </summary>
|
|
/// <param name="logKey">ID del valore log da loggare/verificare</param>
|
|
/// <returns></returns>
|
|
private static bool logValuePermit(string logKey)
|
|
{
|
|
bool doLog = false;
|
|
if (vetoLogError.ContainsKey(logKey))
|
|
{
|
|
// verifico se veto scaduto...
|
|
if (DateTime.Now > vetoLogError[logKey])
|
|
{
|
|
doLog = true;
|
|
vetoLogError[logKey] = DateTime.Now.AddMinutes(vetoPeriodMin);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
doLog = true;
|
|
vetoLogError.Add(logKey, DateTime.Now.AddMinutes(vetoPeriodMin));
|
|
}
|
|
|
|
return doLog;
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
|
|
/// <summary>
|
|
/// Override metodo WebClient con gesitone TimeOut corto
|
|
/// </summary>
|
|
public class WebClientWT : WebClient
|
|
{
|
|
#region Protected Properties
|
|
|
|
/// <summary>
|
|
/// timeout da conf
|
|
/// </summary>
|
|
protected int urlCallTOut
|
|
{
|
|
get
|
|
{
|
|
int answ = 5000;
|
|
answ = baseUtils.CRI("urlCallTOut");
|
|
if (answ < 0 || answ > 10000)
|
|
{
|
|
answ = 3000;
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Protected Methods
|
|
|
|
protected override WebRequest GetWebRequest(Uri address)
|
|
{
|
|
WebRequest wr = base.GetWebRequest(address);
|
|
wr.Timeout = urlCallTOut; // timeout in milliseconds (ms)
|
|
return wr;
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
}
|
|
} |